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

Drupal → Создание табличной формы

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

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

Табличная форма

Небольшая вводная информация — при создании любых табличных форм, я обычно применяю принцип прогрессивного улучшения. Т.е. первым делом создаю форму как если бы я ничего не знал о темизации, но форма при этом должна быть полностью рабочая и понятно выглядеть. Например вот так выглядит наша табличная форма без использования темизации:

Форма без темизации

Ну а вторым шагом, с помощью темизации, придаю ей необходимый вид:

Форма в виде таблицы после применения темизации

Если следовать такому принципу, то достаточно легко создавать формы любой сложности.

Итак, код с комментариями:

/**
 * Form builder.
 */
function modulename_massedit_form($form, &$form_state) {
  $form['nodes'] = array(
    '#tree' => TRUE,
    '#theme' => 'tabular_form', // Функция, с помощью которой мы будем придавать форме табличный вид
    '#header' => array('Дата создания', 'Заголовок', 'Опубликовано'), // Заголовок таблицы
  );
 
  $nodes = db_query("SELECT nid, title, created, status FROM {node}");
 
  foreach ($nodes as $node) {
    $form['nodes'][$node->nid]['created'] = array(
      '#markup' => format_date($node->created, 'small'),
    );
 
    $form['nodes'][$node->nid]['title'] = array(
      '#type' => 'textfield',
      '#default_value' => $node->title,
      '#required' => TRUE,
    );
 
    $form['nodes'][$node->nid]['status'] = array(
      '#type' => 'checkbox',
      '#default_value' => $node->status,
    );
  }
 
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Сохранить',
  );
 
  return $form;
}
 
/**
 * Implements hook_theme().
 */
function modulename_theme() {
  return array(
    'tabular_form' => array(
      'render element' => 'form',
    ),
  );
}
 
/**
 * Format form as table.
 */
function theme_tabular_form($vars) {
  $form = $vars['form'];
  $rows = array();
 
  foreach (element_children($form) as $key) {
    foreach (element_children($form[$key]) as $name) {
      $rows[$key][] = drupal_render($form[$key][$name]);
    }
  }
 
  return theme('table', array(
    'rows' => $rows,
    'header' => $form['#header'],
  ));
}

Я уже писал про то, как создавать формы в виде таблицы, на примере формы удаления нод, но этот способ более универсальный — здесь темизируется только часть формы ($form['nodes']) и в функции темизации не нужно перечислять поля таблицы, они выводятся в порядке определения.

Рабочий пример можно посмотреть в демо-модуле (там чуть усовершенствованная функция theme_tabular_form(), позволяющая добавлять атрибуты таблице, строкам и ячейкам таблицы).

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

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

Уважаемый автор какой 'page callback' => должен быть в hook_menu ???

drupal_get_form

'page arguments' => array('sprice_uniona_mass_edit'), ???

так точно

Что делать если форма в fieldset? После drupal_render(), fieldset выводится отдельно, пустым.

$form['fieldset'] = array('#type' => 'fieldset', '#title' => 'fieldset');
$form['fieldset']['table'] = ...
$form['fieldset']['table']['header'] = ...
$form['fieldset']['table']['data'] = ...
$form['fieldset']['submit'] = ...

1) не вижу где происходит drupal_write_record().

в mymodule_mass_edit_submit

Спасибо, нашел в примере - $node_save().
Допустим сохраняем данные кастомной таблице (прописанной в $schema) и пользователь поменял несоклько записей

$data = array ('id'=>'1', 
  'name'=> 'vasya', // (было вася)
  'gorod'=> '2', //(было 3)
 
$data = array ('id'=>'2', 
  'name'=> 'kolya', // (было колян)
  'gorod'=> '2', //(было 3)

Вопросец: надо каждую отдельно строку с полями сохранять drupal_write_record($table, $data, 'id') - получилось!
или можно как-то сразу все поля всех строк "хором" передать в drupal_write_record ?

сохранять по отдельности

Спасибо за подробные и познавательные статьи. Ваш блог очень помогает в разборках с Друпалом.

А аналог статьи по таблицам и чекбоксам для drupal 7 есть ? ... или там все так же ? Есть ли подводные камни?

Хочу присоединиться к уважаемому semasping.
Огромное Вам человеческое спасибо, отличный блог.
Желаю успехов.

Кто будет делать в D7, есть небольшое отличие в API. Ниже пример для D7.

/**
 * Реализация hook_theme()
 * Регистрируем ф-ю tabular_form, которая будет собирать форму в таблицу
 */
function mymodule_theme() {
    return array(
        'tabular_form' => array('render element' => 'table'),
    );
}
 
/**
 * Реализация функции темизации tabular_form
 */
function theme_tabular_form($elements) {
  $rows = array();
  foreach (element_children($elements['table']['data']) as $key) {
    foreach (element_children($elements['table']['data'][$key]) as $name) {
      $rows[$key][] = drupal_render($elements['table']['data'][$key][$name]);
    }
  }
 
  return theme('table', array('header' => $elements['table']['header']['#value'], 'rows' => $rows));
}

Станислав Романов, спасибо за комментарий о семерке, - очень помогло!

Можно ли в семерке в функцию темизации помимо элемента, еще и form_state передать. В частности нужно form_state['trigger_element'].

а как быть если нужена вертикальная колонка radio buttons? как их в цыкл запихнуть?

Пример обрадовал до слез)) пол дня лазил по англоязычным источникам, чтобы разобраться как в фиэлдсеты вывести таблицы, а тут простой рабочий пример причем в котором отлично показано как переработать отдельные части формы.

Может кому пригодится, что получилось в итоге можно глянуть тут http://pastebin.com/xxa8uRr6

Полезная статья. Сначала сделал по данному туториалу, потом добавил еще draggable c вот этого https://www.curveagency.com/blog/creating-form-draggable-elements-using-...

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

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

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