Создаем разные виды Drupal HTML таблиц (часть 2)
Опубликовано пт, 11/09/2015 - 23:59
Как и обещал, представляю продолжение статьи часть 1. Хук меню, описывающий страницу отображения каждого вида таблиц абсолютно идентичен из первой части, поэтому дублировать его не будем. Будут использованы те же имена функций MYMODULE_tables_page() и MYMODULE_get_all_nodes(). Их содержимое будет также описано (или указано) для каждого из рассматриваемых видов.
Содержание
- Таблица с иерархией строк
- Draggable таблица с возможностью выбора строк
- Таблица блоков (как на странице admin/structure/blocks)
- Таблица с фильтром
Таблица с иерархией строк
Довольно распространенный вид таблиц. Первое, что приходит в голову - это таблица терминов таксономии, таблица меню со ссылками. В данном виде таблиц можно указать родительский и дочерний элемент.
По традиции начнем с hook_theme(). В файле MYMODULE.module
1 2 3 4 5 6 7 8 9 10 11 |
/** * Implements hook_theme(). */ function MYMODULE_theme() { return array( 'hierarchy' => array( 'render element' => 'form', 'file' => 'MYMODULE.theme.inc', ), ); } |
Не забудем упомянуть функцию по выборке необходимых значений из таблицы node.
1 2 3 4 5 6 7 8 9 10 |
/** * Get nodes data. */ function MYMODULE_get_all_nodes() { return db_select('node', 'n') ->fields('n', array('nid', 'type', 'title', 'created')) ->condition('n.status', NODE_PUBLISHED) ->execute() ->fetchAllAssoc('nid'); } |
Далее идет описание функции MYMODULE_tables_page()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/** * Example tables page. */ function MYMODULE_tables_page() { $nodes = MYMODULE_get_all_nodes(); $form['table'] = array( '#type' => 'container', '#theme' => 'hierarchy', ); foreach ($nodes as $nid => $node) { // Идентификатор строки (в нашем случае ID ноды). $form['table'][$nid]['rowid'] = array( '#type' => 'hidden', '#value' => $nid, ); // Элемент формы, отвечающий за иерархию в дереве. $form['table'][$nid]['depth'] = array( '#type' => 'hidden', // Здесь должно быть сохраненное значение порядка иерархии. '#default_value' => '', ); // Элемент формы, отвечающий за родительскую связь. $form['table'][$nid]['parent'] = array( '#type' => 'hidden', // Здесь должно быть сохраненное значение ID родительского элемента // (в нашем случае ID родительской ноды). '#default_value' => '', ); $form['table'][$nid]['title'] = array( '#markup' => $node->title, ); $form['table'][$nid]['type'] = array( '#markup' => $node->type, ); $form['table'][$nid]['created'] = array( '#markup' => date('d-m-Y H:i', $node->created), ); $form['table'][$nid]['link'] = array( '#type' => 'link', '#title' => t('Edit'), '#href' => $nid . '/edit', ); // Вес. $form['table'][$nid]['weight'] = array( '#type' => 'weight', '#delta' => 10, '#title' => t('Weight'), '#title_display' => 'invisible', '#default_value' => '', ); } return $form; } |
Функция темизации theme_hierarchy(), размещенная в файле MYMODULE.theme.inc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/** * Returns HTML for a hierarchy table. */ function theme_hierarchy($vars) { $form = $vars['form']; $rows = array(); foreach (element_children($form) as $key) { $item = &$form[$key]; // Добавляем css классы к элементам формы. $item['rowid']['#attributes']['class'][] = 'table-rowid'; $item['depth']['#attributes']['class'][] = 'table-depth'; $item['parent']['#attributes']['class'][] = 'table-parent'; $item['weight']['#attributes']['class'][] = 'table-weight'; // Смещение. $indentation = ''; if (!empty($item['depth']['#value'])) { $indentation = theme('indentation', array( 'size' => $item['depth']['#value'], )); } $row = array(); // Заполняем строки отрендеренными элементами. $row[] = $indentation . drupal_render($item['title']); $row[0] .= drupal_render($item['parent']) . drupal_render($item['rowid']) . drupal_render($item['depth']); $row[] = drupal_render($item['type']); $row[] = drupal_render($item['created']); $row[] = drupal_render($item['link']); $row[] = drupal_render($item['weight']); $rows[$key]['data'] = $row; $rows[$key]['class'][] = 'draggable'; } // Шапка таблицы. $header = array( t('Title'), t('Type'), t('Date'), t('Action'), t('Weight'), ); $output = theme('table', array( 'header' => $header, 'rows' => $rows, 'empty' => t('Table is empty'), 'attributes' => array( 'id' => 'table-id', ), )); // Добавляем tableDrag JavaScript поведение. drupal_add_tabledrag('table-id', 'match', 'parent', 'table-parent', 'table-parent', 'table-rowid', FALSE); drupal_add_tabledrag('table-id', 'depth', 'group', 'table-depth', NULL, NULL, FALSE); drupal_add_tabledrag('table-id', 'order', 'sibling', 'table-weight'); $output .= drupal_render_children($form); return $output; } |
В итоге получаем вот такую таблицу
Draggable таблица с возможностью выбора строк
Это симбиоз двух видов таблиц: draggable и tableselect. Из коробки друпал не предоставляет такой вид таблиц, поэтому придется "извращаться":)
Опишем хук темы.
1 2 3 4 5 6 7 8 9 10 11 |
/** * Implements hook_theme(). */ function MYMODULE_theme() { return array( 'drag_tableselect' => array( 'render element' => 'form', 'file' => 'MYMODULE.theme.inc', ), ); } |
Содержимое функции MYMODULE_tables_page() приведено ниже. Элемент формы weight не содержит атрибутов #theme, #theme_wrappers, #pre_render. Именно поэтому вызов напрямую drupal_render() возвращает пустую строку. Скорее всего в данной ситуации есть несколько корректных решений, но мы применим следующее: вызовем процесс функцию form_process_weight() напрямую, которая в свою очередь преобразует элемент weight в элемент select.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
/** * Example tables page. */ function MYMODULE_tables_page() { $nodes = MYMODULE_get_all_nodes(); $options = array(); // Элемент веса. $weight = array( '#type' => 'weight', '#delta' => 10, '#title' => t('Weight'), '#title_display' => 'invisible', '#default_value' => 0, '#attributes' => array( 'class' => array('drag-order-weight'), ), ); $weight = form_process_weight($weight); // Заполняем массив options. foreach ($nodes as $nid => $node) { $options[$nid][] = $node->title; $options[$nid][] = $node->type; $options[$nid][] = date('d-m-Y H:i', $node->created); $options[$nid][] = l(t('Edit'), $nid . '/edit'); $options[$nid][] = $weight; } // Шапка таблицы. $header = array( t('Title'), t('Type'), t('Date'), t('Action'), t('Weight'), ); $form['table'] = array( '#type' => 'tableselect', '#theme' => 'drag_tableselect', '#header' => $header, '#options' => $options, '#empty' => t('No content available.'), ); return $form; } |
Несмотря на то, что тема theme_drag_tableselect() будет очень похожа на тему theme_tableselect(), нам необходимо указать тип tableselect элементу table. Это позволит использовать препроцесс функцию для чекбоксов, которая уже реализована для типа элемента формы tableselect.
Подошли непосредственно к самой темирующей функции.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
/** * Returns HTML for drag_tableselect table. */ function theme_drag_tableselect($vars) { $form = $vars['form']; $rows = array(); $header = $form['#header']; if (!empty($form['#options'])) { // Генерируем строку таблицы. foreach (element_children($form) as $key) { $row = array(); $row['data'] = array(); if (isset($form['#options'][$key]['#attributes'])) { $row += $form['#options'][$key]['#attributes']; } // Рендерим чекбокс/радиокнопку. $row['data'][] = drupal_render($form[$key]); $row['class'][] = 'draggable'; // Заполняем остальные ячейки. foreach ($form['#header'] as $fieldname => $title) { $item = $form['#options'][$key][$fieldname]; $row['data'][] = is_array($item) ? drupal_render($item) : $item; } $rows[] = $row; } // Отображем доп. чекбокс "Выбрать все". if ($form['#js_select']) { drupal_add_js('misc/tableselect.js'); array_unshift($header, array('class' => array('select-all'))); } else { // Добавляем пустую ячейку в шапку таблицы в случае, когда отоюражаем // радиокнопки или когда не нужно отображать чекбокс "Выбрать все". array_unshift($header, ''); } } $form['#attributes']['id'] = 'drag-tableselect-id'; drupal_add_tabledrag('drag-tableselect-id', 'order', 'sibling', 'drag-order-weight'); return theme('table', array( 'header' => $header, 'rows' => $rows, 'empty' => $form['#empty'], 'attributes' => $form['#attributes'], )); } |
Результат
Таблица блоков (как на странице admin/structure/blocks)
Очень интересный вид таблицы. Из коробки также нет удобного инструмента для создания данной таблицы. Для большей наглядности возьмем таблицу базы данных, в которой есть связь родитель-потомок, например, таблица menu_links.
Объявляем hook_theme() в MYMODULE.module. Помимо основной темирующей функции (назовем ее blocks_table) еще потребуется шаблон blocks_table_template. Шаблон находится в папке templates.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/** * Implements hook_theme(). */ function MYMODULE_theme() { return array( 'blocks_table' => array( 'render element' => 'form', 'file' => 'MYMODULE.theme.inc', ), 'blocks_table_template' => array( 'template' => '/templates/MYMODULE-blocks-table', 'variables' => array( 'rows' => array(), 'cells' => array(), 'header' => array(), 'empty' => NULL, ), ), ); } |
Функция MYMODULE_tables_page() примет следующий вид.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
/** * Example tables page. */ function MYMODULE_tables_page($form, $form_state) { // Массив меню объектов. $menus = MYMODULE_get_menus(); $form['table'] = array( '#theme' => 'blocks_table', '#tree' => TRUE, ); // Подключение необходимых файлов js и css. $path = drupal_get_path('module', 'MYMODULE'); $form['table']['#attached']['css'][] = $path . '/css/MYMODULE.css'; $form['table']['#attached']['js'][] = $path . '/js/MYMODULE.js'; // Формируем заголовки регионов. $regions = array(); foreach ($menus as $menu_name => $menu) { $regions[$menu_name] = $menu->title; $form['table']['rows'][$menu_name]['name'] = array( '#markup' => $menu->title, ); } // Список ссылок меню. $links = MYMODULE_get_menu_links(); // Формируем массив ячеек, которые будут располагаться в строке. foreach ($links as $mlid => $link) { $menu = $link->menu_name; $form['table']['cells'][$menu][$mlid]['link_title'] = array( '#markup' => $link->link_title, ); $form['table']['cells'][$menu][$mlid]['link_path'] = array( '#markup' => $link->link_path, ); $form['table']['cells'][$menu][$mlid]['menu_name'] = array( '#markup' => $link->menu_name, ); $form['table']['cells'][$menu][$mlid]['region'] = array( '#type' => 'select', '#default_value' => $menu, '#options' => $regions, '#attributes' => array( 'class' => array('cell-region-select', 'cell-region-' . $menu), ), ); $form['table']['cells'][$menu][$mlid]['weight'] = array( '#type' => 'weight', '#delta' => 20, '#default_value' => 0, '#attributes' => array( 'class' => array('cell-weight', 'cell-weight-' . $menu), ), ); } return $form; } |
Функция MYMODULE_get_menus() возвращает массив меню объектов из таблицы бд menu_custom.
1 2 3 4 5 6 7 8 9 |
/** * Menu list. */ function MYMODULE_get_menus() { return db_select('menu_custom', 'm') ->fields('m') ->execute() ->fetchAllAssoc('menu_name'); } |
Фукнция MYMODULE_get_menu_links() в свою очередь возвращает массив объектов ссылок. Здесь ограничимся ссылками из меню user-menu, количества которых вполне достаточно для демонстрации таблицы и ее работы.
1 2 3 4 5 6 7 8 9 10 |
/** * Get "user-menu" links. */ function MYMODULE_get_menu_links() { return db_select('menu_links', 'm') ->fields('m') ->condition('m.menu_name', 'user-menu') ->execute() ->fetchAllAssoc('mlid'); } |
Содержимое файла MYMODULE.js честно позаимствовано из файла block.js модуля ядра block с минимальными изменениями.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
/** * Позволяет перемещать строки из одного региона в другой. */ (function($){ Drupal.behaviors.CellsDrag = { attach: function (context, settings) { // Проверяем, что присутствует объект tableDrag. if (typeof Drupal.tableDrag == 'undefined' || typeof Drupal.tableDrag.cells == 'undefined') { return; } var table = $('table#cells'); var tableDrag = Drupal.tableDrag.cells; // Обновление пустых регионов, когда строки изменили положение. tableDrag.row.prototype.onSwap = function (swappedRow) { checkEmptyRegions(table, this); }; // Сообщение о необходимости сохранить совершенные изменения. Drupal.theme.tableDragChangedWarning = function () { return '<div class="messages warning">' + Drupal.theme('tableDragChangedMarker') + ' ' + Drupal.t('The changes to these blocks will not be saved until the <em>Save blocks</em> button is clicked.') + '</div>'; }; // Обновление строк, перемещенных в новые регионы. tableDrag.onDrop = function () { var dragObject = this; var regionRow = $(dragObject.rowObject.element).prevAll('tr.row-message').get(0); var regionName = regionRow.className.replace(/([^ ]+[ ]+)*row-([^ ]+)-message([ ]+[^ ]+)*/, '$2'); var regionField = $('select.cell-region-select', dragObject.rowObject.element); if ($('option[value=' + regionName + ']', regionField).length == 0) { alert(Drupal.t('The block cannot be placed in this region.')); regionField.change(); } else if ($(dragObject.rowObject.element).prev('tr').is('.row-message')) { var weightField = $('select.cell-weight', dragObject.rowObject.element); var oldRegionName = weightField[0].className.replace(/([^ ]+[ ]+)*cell-weight-([^ ]+)([ ]+[^ ]+)*/, '$2'); if (!regionField.is('.cell-region-' + regionName)) { regionField.removeClass('cell-region-' + oldRegionName).addClass('cell-region-' + regionName); weightField.removeClass('cell-weight-' + oldRegionName).addClass('cell-weight-' + regionName); regionField.val(regionName); } } }; // Обратчик выбора регионов из выпадющего списка. $('select.cell-region-select', context).once('cell-region-select', function () { $(this).change(function (event) { var row = $(this).closest('tr'); var select = $(this); tableDrag.rowObject = new tableDrag.row(row); table.find('.row-' + select[0].value + '-message').nextUntil('.row-message').last().before(row); checkEmptyRegions(table, row); select.get(0).blur(); }); }); var checkEmptyRegions = function (table, rowObject) { $('tr.row-message', table).each(function () { if ($(this).prev('tr').get(0) == rowObject.element) { if ((rowObject.method != 'keyboard' || rowObject.direction == 'down')) { rowObject.swap('after', this); } } // Регион пуст. if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').length == 0) { $(this).removeClass('row-populated').addClass('row-empty'); } // Регион заполнен. else if ($(this).is('.row-empty')) { $(this).removeClass('row-empty').addClass('row-populated'); } }); }; } } })(jQuery); |
Файл MYMODULE.css содержит миниммум стилей.
1 2 3 4 5 6 7 8 |
.row-populated { display: none; } .row-title { font-weight: bold; text-transform: uppercase; } |
Теперь черед темирующей функции theme_blocks_table().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
/** * Returns HTML for a blocks_table table. */ function theme_blocks_table($vars) { $element = $vars['form']; // Шапка таблицы. $header = array( t('Title'), t('Path'), t('Menu name'), t('Region'), t('Weight'), ); // Инициализируем массив опций. $options = array( 'rows' => array(), 'cells' => array(), ); foreach (element_children($element['rows']) as $name) { $options['rows'][$name] = new stdClass(); $options['rows'][$name]->name = drupal_render($element['rows'][$name]['name']); // Подключаем js draggable поведение. drupal_add_tabledrag('cells', 'match', 'sibling', 'cell-region-select', 'cell-region-' . $name, NULL, FALSE); drupal_add_tabledrag('cells', 'order', 'sibling', 'cell-weight', 'cell-weight-' . $name); if (!empty($element['cells'][$name])) { foreach (element_children($element['cells'][$name]) as $mlid) { $cell = &$element['cells'][$name][$mlid]; $options['cells'][$name][$mlid] = new stdClass(); $options['cells'][$name][$mlid]->link_title = drupal_render($cell['link_title']); $options['cells'][$name][$mlid]->link_path = drupal_render($cell['link_path']); $options['cells'][$name][$mlid]->menu_name = drupal_render($cell['menu_name']); $options['cells'][$name][$mlid]->region = drupal_render($cell['region']); $options['cells'][$name][$mlid]->weight = drupal_render($cell['weight']); } } } // Передаем обработанные данные в шаблон. return theme('blocks_table_template', array( 'header' => $header, 'rows' => $options['rows'], 'cells' => $options['cells'], 'empty' => t('No data'), )); } |
Шаблон MYMODULE-blocks-table.tpl.php содержит следующий код.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<table id="cells" class="sticky-enabled"> <thead> <tr> <?php foreach($header as $title): ?> <th><?php print $title; ?></th> <?php endforeach; ?> </tr> </thead> <tbody> <?php $i = 0; ?> <?php if (!empty($rows)): ?> <?php foreach ($rows as $menu_name => $row): ?> <tr class="row-title row-title-<?php print $menu_name?>"> <td colspan="<?php print count($rows); ?>"><?php print $row->name; ?></td> </tr> <tr class="row-message row-<?php print $menu_name?>-message <?php print empty($cells[$menu_name]) ? 'row-empty' : 'row-populated'; ?>"> <td colspan="<?php print count($rows); ?>"><em><?php print t('No symbols in this region'); ?></em></td> </tr> <?php if (!empty($cells[$menu_name])): ?> <?php foreach ($cells[$menu_name] as $sid => $data): ?> <tr class="draggable <?php print $i % 2 == 0 ? 'odd' : 'even'; ?>"> <td class="cell"><?php print $data->link_title; ?></td> <td><?php print $data->link_path; ?></td> <td><?php print $data->menu_name; ?></td> <td><?php print $data->region; ?></td> <td><?php print $data->weight; ?></td> </tr> <?php $i++; ?> <?php endforeach; ?> <?php endif; ?> <?php endforeach; ?> <?php else: ?> <tr><td colspan="<?php print count($rows); ?>"><?php print $empty; ?></td></tr> <?php endif; ?> </tbody> </table> |
В результате, получаем вот такую табличку
Таблица с фильтром
Таблица с фильтром будет построена на примере простой таблицы, то есть, hook_theme() и theme_simple() будут точно такие же как в первом примере из статьи "Создаем разные виды Drupal HTML таблиц (часть 1)". Изменения коснутся функции выборки MYMODULE_get_all_nodes() и функции MYMODULE_tables_page().
Данные фильтра будем хранить в сессии. Если нужно сделать индивидуальные настройки фильтра для каждого пользователя - используйте cookie.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
/** * Example tables page. */ function MYMODULE_tables_page($form, $form_state) { // Массив дефолтных значений для фильтра. $options = array('title' => '', 'type' => 'noselect'); if (!empty($_SESSION['MYMODULE_filter'])) { $options = $_SESSION['MYMODULE_filter']; } // Подключаем фильтр. MYMODULE_table_filter($form, $form_state, $options); $form['simple_table'] = array( '#type' => 'container', '#theme' => 'simple', ); $nodes = MYMODULE_get_all_nodes($options); foreach ($nodes as $nid => $node) { $form['simple_table'][$nid]['title'] = array( '#markup' => $node->title, ); $form['simple_table'][$nid]['type'] = array( '#markup' => $node->type, ); $form['simple_table'][$nid]['created'] = array( '#markup' => date('d-m-Y H:i', $node->created), ); $form['simple_table'][$nid]['link'] = array( '#type' => 'link', '#title' => t('Edit'), '#href' => $nid . '/edit', ); } return $form; } |
Функция MYMODULE_get_all_nodes() принимает дополнительный аргумент $options - это массив сохраненных значений фильтра (будет участвовать в условиях выборки).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/** * Get nodes data. */ function MYMODULE_get_all_nodes($options) { $query = db_select('node', 'n'); $query->fields('n', array('nid', 'type', 'title', 'created')); $query->condition('n.status', NODE_PUBLISHED); // Проверяем заполнен ли title. if (!empty($options['title'])) { $query->condition('n.title', db_like($options['title']) . '%', 'LIKE'); } // Проверяем, что выбран тип ноды. if ($options['type'] != 'noselect') { $query->condition('n.type', $options['type']); } $result = $query->execute()->fetchAllAssoc('nid'); return $result; } |
Фильтр представляет собой филдсет с текстовым полем для ввода заголовка ноды, селектом для выбора типа и двумя кнопками - "фильтр" и "сброс".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/** * Filter. */ function MYMODULE_table_filter(&$form, &$form_state, $options) { // Разворачиваем или оставляем свернутым филдсет в зависимости от того, // есть значения в сессии или нет. $form['filter'] = array( '#type' => 'fieldset', '#title' => t('Filter'), '#collapsible' => TRUE, '#collapsed' => !empty($_SESSION['MYMODULE_filter']) ? FALSE : TRUE, ); $form['filter']['title'] = array( '#type' => 'textfield', '#title' => t('Title'), '#default_value' => $options['title'], ); $types = array('noselect' => t('No select')); $types += node_type_get_names(); $form['filter']['type'] = array( '#type' => 'select', '#title' => t('Type'), '#options' => $types, '#default_value' => $options['type'], ); $form['filter']['submit'] = array( '#type' => 'submit', '#value' => t('Filter'), '#submit' => array('MYMODULE_filter_submit'), ); $form['filter']['reset'] = array( '#type' => 'submit', '#value' => t('Reset'), '#submit' => array('MYMODULE_filter_reset'), ); return $form; } |
В колбэке для сабмита фильтра добавляем значения в сессию.
1 2 3 4 5 6 7 8 9 10 |
/** * Submit filter callback. */ function MYMODULE_filter_submit($form, $form_state) { $values = $form_state['values']; $_SESSION['MYMODULE_filter'] = array( 'title' => $values['title'], 'type' => $values['type'], ); } |
Соответственно в reset колбэке - удаляем массив данных из сессии.
1 2 3 4 5 6 |
/** * Reset filter callback. */ function MYMODULE_filter_reset($form, $form_state) { unset($_SESSION['MYMODULE_filter']); } |
Таблица с фильтром (добавлены минимальные css стили для выравнивания блоков в фильтре).
1 Комментарий
Павел - чт, 09/02/2017 - 17:31
Спасибо
Спасибо