Таблица с перетаскиванием строк

Draggable table

Опубликовал Максим Баев, 30 апреля 2014, 10:08

Таблицы с перетаскиванием строк создаются немного сложнее чем простые таблицы. Вся логика создания такой таблицы заключается в том, чтобы вручную произвести рендеринг формы и разложить элементы формы по строкам. После чего запустить функцию drupal_add_tabledrag() с какими-то параметрами. И вот как это делается (комментарии в коде). Создание таблицы с перетаскиванием строк (установкой веса)

<?php
/**
 * Реализация hook_menu()
 * Объявляем пути страниц модуля
 */
function new_menu(){
  $items['new-test'] = array(
    'title'           => 'New tabledrag',
    'page callback'   => 'drupal_get_form',
    'page arguments'  => array('new_some_form'),
    'access callback' => TRUE,
  );
  return $items;
}

/**
 * Данные для таблицы.
 * Здесь может быть запрос в базу.
 */
function new_results(){
  $x = 0;
  return array(
    (object) array(
      'id'          => ++$x,
      'name'        => 'name-' . $x,
      'description' => 'description-' . $x,
      'weight'      => $x
    ),
    (object) array(
      'id'          => ++$x,
      'name'        => 'name-' . $x,
      'description' => 'description-' . $x,
      'weight'      => $x
    ),
    (object) array(
      'id'          => ++$x,
      'name'        => 'name-' . $x,
      'description' => 'description-' . $x,
      'weight'      => $x
    ),
    (object) array(
      'id'          => ++$x,
      'name'        => 'name-' . $x,
      'description' => 'description-' . $x,
      'weight'      => $x
    ),
  );
}

/**
 * Реализация hook_form()
 * Создаём форму, которую затем будем помещать в таблицу
 */
function new_some_form($form, &$form_state){
  // example_items - вложения будут ячейками таблицы
  // сохранение древовидности обязательно
  $form['example_items']['#tree'] = TRUE;

  foreach (new_results() as $item){
    $form['example_items'][$item->id] = array(
      'name'        => array(
        '#markup' => check_plain($item->name),
      ),
      'description' => array(
        '#type'          => 'textfield',
        '#default_value' => check_plain($item->description),
        '#size'          => 20,
        '#maxlength'     => 255,
      ),
      'weight'      => array(
        '#type'          => 'weight',
        '#title'         => t('Weight'),
        '#default_value' => $item->weight,
        '#delta'         => 10,
        '#title_display' => 'invisible',
      ),
    );
  }

  $form['actions']           = array(
    '#type' => 'actions'
  );
  $form['actions']['submit'] = array(
    '#type'  => 'submit',
    '#value' => t('Save Changes')
  );
  return $form;
}

/**
 * Реализация hook_theme()
 */
function new_theme(){
  return array(
    /**
     * Ключ должен совпадать с названием формы.
     * Когда друпал будет искать функцию темизации
     * он к названию формы будет подставлять "theme_"
     * theme_{$key} => theme_new_form
     */
    'new_some_form' => array(
      'render element' => 'form',
    ),
  );
}

/**
 * Темизация формы.
 * Имя должно совпадать с названием формы
 * (а точнее с тем ключем, который мы указали в хуке темы),
 * но в начало должно быть добавлено "theme_"
 */
function theme_new_some_form($variables){
  $form = $variables['form'];
  $rows = array();
  // класс для строки таблицы
  $row_class = 'new-table-row';
  // id таблицы
  $table_id = 'new-table-id';

  // пробежка по дочерним элементам формы
  foreach (element_children($form['example_items']) as $id){
    // обязательный класс строк для таблицы с drop&drag

    $form['example_items'][$id]['weight']['#attributes']['class'] = array($row_class);
    // рендерим каждый элемент формы и засовывем его в ячейку строки
    $rows[] = array(
      'data'  => array(
        drupal_render($form['example_items'][$id]['name']),
        drupal_render($form['example_items'][$id]['description']),
        drupal_render($form['example_items'][$id]['weight']),
      ),
      // обязательный класс
      'class' => array('draggable'),
    );
  }
  // заголовки таблицы
  $header = array(t('Name'), t('Description'), t('Weight'));
  // темизируем как обычную таблицу
  $output = theme('table', array(
      'header'     => $header,
      'rows'       => $rows,
      'attributes' => array('id' => $table_id),
    )
  );

  // рендерим то что осталось от формы
  $output .= drupal_render_children($form);

  // вот тут и случается все волшебство
  drupal_add_tabledrag($table_id, 'order', 'sibling', $row_class);
  return $output;
}

Результат:

image image

Другие посты