4.3.1. Создание списков

Data Source

Эта статья еще не закончена!

Вы видите это сообщение, поскольку текущая статья еще не закончена или содержит непроверенную информацию. Как написать статью.

Данная статья посвящена созданию списков (или Grid) в стандартизированной административной части проекта.

Списки позволяют выводить сколь угодно большой объем табличных данных в виде списка, разбитого по страницам.

Каждый элемент списка можно

  • сортировать по убыванию или возрастанию.

  • устанавливать фильтр по значению.

  • скрывать из списка.

  • изменять местоположение относительно других элементов списка.

Дополнительно при помощи настроек списка можно

  • изменять кол-во выводимых элементов на странице.

  • выделять все элементы на текущей странице или все элементы списка на всех страницах.

  • настраивать поле и порядок сортировки по умолчанию

  • при помощи кнопок Search и Reset можно фильтровать список по необходимому количеству фильтров.

Есть специальные кнопки для добавления, редактирования или удаления любого элемента списка.

Пример списка

Пример списка

Шаблон списка

Пример стандартного шаблона списка.

  • Префикс: demo.

  • Файл: demo_list.tpl.

<inp2:m_include t="incs/header"/>
<inp2:m_RenderElement name="combined_header" section="custom:demo" prefix="demo" pagination="1"/>

<!-- ToolBar --->
<table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
    <tr>
        <td>
            <table width="100%" cellpadding="0" cellspacing="0">
                <tr>
                    <td>
                        <script type="text/javascript">
                            a_toolbar = new ToolBar();

                            a_toolbar.AddButton(
                                new ToolBarButton(
                                    'new_item',
                                    '<inp2:m_phrase label="la_ToolTip_Newdemo" escape="1"/>::<inp2:m_phrase label="la_Add" escape="1"/>',
                                    function() {
                                        std_precreate_item('demo', 'custom/demo/demo_edit');
                                    }
                                )
                            );

                            function edit()
                            {
                                std_edit_item('demo', 'custom/demo/demo_edit');
                            }

                            a_toolbar.AddButton(
                                new ToolBarButton(
                                    'edit',
                                    '<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>::<inp2:m_phrase label="la_ShortToolTip_Edit" escape="1"/>',
                                    edit
                                )
                            );

                            a_toolbar.AddButton(
                                new ToolBarButton(
                                    'delete',
                                    '<inp2:m_phrase label="la_ToolTip_Delete" escape="1"/>',
                                    function() {
                                        std_delete_items('demo');
                                    }
                                )
                            );

                            a_toolbar.AddButton( new ToolBarSeparator('sep1') );

                            a_toolbar.AddButton(
                                new ToolBarButton(
                                    'view',
                                    '<inp2:m_phrase label="la_ToolTip_View" escape="1"/>',
                                    function(id) {
                                        show_viewmenu(a_toolbar,'view');
                                    }
                                )
                            );

                            a_toolbar.Render();
                        </script>
                    </td>

                    <inp2:m_RenderElement name="search_main_toolbar" prefix="demo" grid="Default"/>
                </tr>
            </table>
        </td>
    </tr>
</table>

<inp2:m_RenderElement name="grid" PrefixSpecial="demo" IdField="DemoId" grid="Default" grid_filters="1"/>

<script type="text/javascript">
    Grids['demo'].SetDependantToolbarButtons( new Array('edit', 'delete') );
</script>

<inp2:m_include t="incs/footer"/>

Данный шаблон реализует самый простой вариант списка и состоит из следующих основных частей.

  • вызов блока combined_header для показа заголовка списка.

<inp2:m_RenderElement name="combined_header" section="custom:demo" prefix="demo" pagination="1"/>
  • инициализация блока кнопок.

a_toolbar = new ToolBar();
  • код для показа кнопки добавления новой записи.

a_toolbar.AddButton(
    new ToolBarButton(
        'new_item',
        '<inp2:m_phrase label="la_ToolTip_Newdemo" escape="1"/>::<inp2:m_phrase label="la_Add" escape="1"/>',
        function() {
            std_precreate_item('demo', 'custom/demo/demo_edit');
        }
    )
);
  • код для показа кнопки редактирования записи.

function edit()
{
    std_edit_item('demo', 'custom/demo/demo_edit');
}

a_toolbar.AddButton(
    new ToolBarButton(
        'edit',
        '<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>::<inp2:m_phrase label="la_ShortToolTip_Edit" escape="1"/>',
        edit
    )
);
  • код для показа кнопки удаления записи.

a_toolbar.AddButton(
    new ToolBarButton(
        'delete',
        '<inp2:m_phrase label="la_ToolTip_Delete" escape="1"/>',
        function() {
            std_delete_items('demo');
        }
    )
);
  • код для показа разделителя между кнопками.

a_toolbar.AddButton( new ToolBarSeparator('sep1') );
  • код для показа выпадающего меню с настройками списка.

a_toolbar.AddButton(
    new ToolBarButton(
        'view',
        '<inp2:m_phrase label="la_ToolTip_View" escape="1"/>',
        function(id) {
            show_viewmenu(a_toolbar,'view');
        }
    )
);
  • вызов блока для показа кнопок Search и Reset.

<inp2:m_RenderElement name="search_main_toolbar" prefix="demo" grid="Default"/>
  • вызов блока grid, который собственно и печатает сам список. Этому блоку будет посвящен отдельный раздел в статье.

<inp2:m_RenderElement name="grid" PrefixSpecial="demo" IdField="DemoId" grid="Default" grid_filters="1"/>
  • настройка зависимых кнопок на панели инструментов, в зависимости от выбранных в списке записей.

Grids['demo'].SetDependantToolbarButtons( new Array('edit', 'delete') );

Описание параметров блока «Grid»

Пример типичного вызова блока "Grid" с базовым набором параметров.

<inp2:m_ParseBlock name="grid" PrefixSpecial="demo" IdField="DemoId" grid="Default"/>

Расширенный пример вызова блока "Grid". Добавлены параметры grid_filters, limited_heights, max_row_height.

<inp2:m_ParseBlock name="grid" PrefixSpecial="demo" IdField="DemoId" grid="Default"  grid_filters="1" limited_heights="true" max_row_height="100"/>

Описание основных параметров блока "Grid".

параметр

описание

name (string)

Название блока для отображения списка, по умолчанию это «grid».

PrefixSpecial (string)

Название текущего PrefixSpecial для текущего списка.

IdField (string)

Название поля IDField из конфигурационного файла префикса demo.

grid (string)

Название текущего списка из раздела Grids конфигурационного файла префикса demo.

grid_filters (int)

Опция устанавливает показ фильтров на списке.

limited_heights (boolean)

Добавлено в версии RC_feb08_1.

Опция устанавливает ограничение на высоту элементов списка (измеряется в пикселях).

max_row_height (int)

Добавлено в версии RC_feb08_1.

Опция устанавливает максимальное значение для высоты элементов списка в пикселях (измеряется в пикселях).

Описание дополнительных параметров блока "Grid".

параметр

описание

per_page (int)

Количество записей на 1 странице, по умолчанию это 10 записей.

no_toolbar (string)

Опция убирает показ toolbar с фильтрами на списке. Нужно поставить значение no_toolbar="no_toolbar".

search (string)

Опция выводит отдельный общий элемент поиска по колонкам из списка. По умолчанию установлено значение on.

header_block (string)

Название блока для вывода заголовков колонок списка. По умолчанию установлено значение grid_column_title.

filter_block (string)

Название блока для вывода фильтра колонки. По умолчанию установлено значение grid_column_filter.

data_block (string)

Название блока для вывода значения записи. По умолчанию установлено значение grid_data_td.

totals_block (string)

Название блока для вывода суммарного значения записей в колонке. По умолчанию установлено значение grid_total_td.

row_block (string)

Название блока для вывода тега tr при печати списка. По умолчанию установлено значение _row.

totals (int)

Параметр указывает списку, что при печати будут выводиться блоки с суммарным значением. По умолчанию установлено значение 0.

grid_height (string)

Добавлено в версии RC_aug08_1.

Параметр задает списку высоту. По умолчанию установлено значение auto чтобы использовать всю доступную высоту. Параметр измеряется в пикселях.

no_special (int)

Добавлено в версии RC_aug08_1.

Параметр устанавливает, будут ли специальные символы преобразовываться в HTML. Пример no_special="no_special". Пробовал на символе & quot - у меня сработало (специально проверил). По умолчанию установлено значение 0.

selector (string)

Добавлено в версии RC_aug08_1.

Название HTML элемента для индикатора редактирования записи. По умолчанию установлено значение checkbox. Чтобы изменить значение параметра, надо в описание параметров текущего списка в конфигурационном файле указать в опции „Selector“ требуемый элемент. Например 'Selector' => 'radio'.

grid_status (int)

Добавлено в версии RC_aug08_1.

Параметр устанавливает, будут ли показан блок со статистикой количества записей. По умолчанию установлено значение 1.

Настройка зависимых (от выбранных в списке записей) кнопок на панели инструментов

Есть ситуации, когда кнопки на панели инструментов могут быть доступны (активны) или не доступны (не активны).

Например:

  • Кнопка Add (добавить запись) доступна всегда, т.к. пользователь должен иметь возможность всегда добавить новую запись.

  • Кнопка Edit (редактировать запись) должна быть активна, только тогда когда пользователь выбрал запись из списка для редактирования.

Для регулирования данного процесса в шаблоне списка есть следующий код:

Grids['newsletter'].SetDependantToolbarButtons( new Array('delete', 'edit', 'move_up', 'move_down', 'new_review', 'e-mail') );

В массиве нужно перечислить все названия кнопок которые зависимы от состояния выбранности записи, т.е. если запись не выбрана кнопка не активна, если выбрана, то активна.

Название кнопки, это 1 параметр для создания экземпляра класса new ToolBarButton.

Пример кнопки edit:

a_toolbar.AddButton(
    new ToolBarButton(
        'edit',
        '<inp2:m_phrase label="la_ToolTip_Edit" escape="1"/>::<inp2:m_phrase label="la_ShortToolTip_Edit" escape="1"/>',
        edit
    )
);

Задание описания списка в unit config (ключ Grids)

Пример массива Grids.

'Grids' => Array(
    'Default' => Array(
        'Icons' => Array('default'=>'icon16_folder.gif'),
        'Fields' => Array(
            'DemoId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td'),
            'Title' => Array( 'title'=>'la_col_Title'),
            'Image' => Array( 'title'=>'la_col_Image', 'data_block' => 'image_td'),
            'Date' => Array( 'title'=>'la_col_Date', 'filter_block' => 'grid_date_range_filter')
        ),
    ),
)
  • Default - это название списка, которое нужно указывать при вызове блоков grid, search_main_toolbar

// grid
<inp2:m_ParseBlock name="grid" PrefixSpecial="demo" IdField="DemoId" grid="Default" grid_filters="1" limited_heights="true" max_row_height="20"  search="1"/>

// search_main_toolbar
<inp2:m_RenderElement name="search_main_toolbar" prefix="demo" grid="Default"/>
  • Icons - секция, где можно указать иконку по умолчанию, которая показывается в начале каждой записи списка.

  • массив Fields служит для описания списка выводимый на странице полей. Название элементов этого массива соответствует названиям полей из основного массива Fields.

Описание основных параметров элементов массива Fields

название

описание

title (string)

Название фразы для колонки поля

data_block (string)

Можно указать название специального блока для отображения ячейки записи, например 'data_block' => 'image_td'.

Если не указан данный ключ, то используются название по умолчанию - grid_data_td. Для поля, которое выводит колонку с значениями IDField нужно указывать блок grid_checkbox_td.

filter_block (string)

Название блока для фильтра колонки. Значение по умолчанию grid_column_filter, т.е. фильтр типа LIKE. Доступны следующие блоки фильтров: grid_options_filter, grid_picker_filter, grid_like_combo_filter, grid_equals_filter, grid_range_filter, grid_float_range_filter, grid_date_range_filter.

Описание блоков фильтров

Фильтр

Изображение

Описание

grid_column_filter

Стандартный фильтр

Стандартный фильтр

Фильтр по умолчанию, типа LIKE.

grid_options_filter

Выпадающий фильтр

Выпадающий фильтр

Фильтр в виде выпадающего списка для Field с kOptionFormatter. Например список размеров картинок.

grid_picker_filter

Аналогично grid_options_filter

Фильтр позволяет устанавливать значения для поиска в поле, которое редактируется через блоки inp_edit_picker, inp_edit_multioptions, inp_edit_checkboxes.

grid_like_combo_filter

Advanced LIKE фильтр

Advanced LIKE фильтр

Модернизированная версия LIKE фильтра, которая по мере ввода значения, показывает результаты поиска.

grid_equals_filter

Фильтр по значению

Фильтр по значению

Фильтр для поиска по 1 значению.

grid_range_filter

Фильтр по диапазону значений

Фильтр по диапазону значений

Фильтр для поиска по диапазону числовых значений. Например от 10 до 20.

grid_float_range_filter

Аналогично grid_range_filter

Фильтр для поиска по диапазону дробных значений. Например от 10.35 до 20.89.

grid_date_range_filter

Фильтр по диапазону значений дат

Фильтр по диапазону значений дат

Фильтр для поиска по диапазону дат. При нажатие на иконку календаря, можно через удобный интерфейс выбрать необходимую дату и установить время.

Задание сортировки списков в unit config

Сортировка для списка задается в массиве ListSortings. Для каждого special можно задать свои варианты сортировки. По умолчанию задается общая сортировка для префикса.

'ListSortings'  =>  Array(
    '' => Array (
        'ForcedSorting' => Array('Priority' => 'desc'),
        'Sorting'   => Array('Name' => 'asc')
    ),
    'front' => Array (
        'Sorting'   => Array('Date' => 'desc', 'Name' => 'asc' )
    )
)
  • Секция ForcedSorting используется для установки 1-го поля для сортировки и все остальные сортировки уже сортируют список, который был отсортирован по полю, указанному в ForcedSorting. Отметить через интерфейс эту установку поиска нельзя.

Ключ элемента массива Priority - это поле сортировки. Значение элемента массива desc - это направление сортировки.

  • Секция Sorting задает поля и направления обычной сортировки по умолчанию. При нажатии на ссылку сортировки на списке записей поле сортировки и ее направление может быть изменено.

Массив ConfigMapping служит для задания значений полей, направлений сортировки и значений для разделения списка нс страницы, на основе опций конфигурации, которые хранятся в таблице ConfigurationValues.

'ConfigMapping' =>  Array(
    'PerPage'       =>  'Comm_Perpage_Demos',
    'ShortListPerPage'  =>  'Comm_Perpage_Demos_Short',
    'DefaultSorting1Field'  =>  'demo_OrderDemoBy',
    'DefaultSorting2Field'  =>  'demo_OrderDemoThenBy',
    'DefaultSorting1Dir'    =>  'demo_OrderDemoByDir',
    'DefaultSorting2Dir'    =>  'demo_OrderDemoThenByDir'
)

Ключ элемента массива PerPage. Значение элемента массива Comm_Perpage_Demos - переменная из таблицы ConfigurationValues.

название

описание

PerPage (string)

Количество записей на страницу. Пример задания в шаблоне <inp2:demo_InitList per_page="per_page"/>.

ShortListPerPage (string)

Количество записей на страницу для укороченного списка. Например нужно вывести на главной странице только 5 последних новостей, а на остальных страницах список выводит по 10 записей. Пример задания в шаблоне <inp2:demo_InitList per_page="per_page"/>.

DefaultSorting1Field (string)

Название 1 - го поля для сортировки.

DefaultSorting2Field (string)

Название 2 - го поля для сортировки.

DefaultSorting1Dir (string)

Направление сортировки для 1 - го поля.

DefaultSorting2Dir (string)

Направление сортировки для 2 - го поля.

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

Описание тэга IterateGridFields

Метод IterateGridFields из kDBTagProcessor предназначен для вывода элементов списка в администраторской части сайта таких как названия колонок, фильтров колонок, значений ширины колонок и т.д.

В общем виде вызов метода следующий

<inp2:$prefix_IterateGridFields grid="$grid" mode="$mode" block="$header_block" ajax="$ajax" no_special="$no_special"/>

Метод может работать в 6 режимах.

  • Выводит 1 ряд значений записей списка в режиме mode="data" при помощи блока grid_data_td.

  • Печатает заголовки колонок списка в режиме mode="header" при помощи блока grid_column_title.

  • Выводят фильтры для каждой колонки в режиме mode="filter" при помощи блока grid_column_filter.

  • Устанавливает ширину в пикселях для каждой колонки. Режим mode="width".

  • Получает список Fields из конфигурационного файла в виде массива. Режим mode="fields". При этом не используется блок. Результат в виде JavaScript массива с названиями полей.

  • Выводит значение totals для колонки в режиме mode="data", при этом используются блок grid_total_td.

Рассмотрим что же делает метод IterateGridFields.

function IterateGridFields($params)
{
    // Параметр $mode нужен для задания специального блока при вызове метода
    $mode = $params['mode'];
    // По умолчанию метод берет название блока из параметра block
    $def_block = isset($params['block']) ? $params['block'] : '';
    // Если нужно жестко задать определенный блок, то есть параметр force_block для этого
    $force_block = isset($params['force_block']) ? $params['force_block'] : false;

    // метод получает массив Fields для текущего Grid
    $grids = $this->Application->getUnitOption($this->Prefix,'Grids');
    $grid_config = $grids[$params['grid']]['Fields'];

    // вызывает ColumnPickerHelper
    $picker_helper =& $this->Application->RecallObject('ColumnPickerHelper');
    /* @var $picker_helper kColumnPickerHelper */
    $picker_helper->ApplyPicker($this->getPrefixSpecial(), $grid_config, $params['grid']);

    // возвращает результат в виде JavaScript массива с названиями полей в режиме $mode == 'fields'
    if ($mode == 'fields') {
        return "'".join("','", array_keys($grid_config))."'";
    }

    // устанавливает стандартные параметры блока
    $std_params['pass_params'] = 'true';
    $std_params['PrefixSpecial'] = $this->getPrefixSpecial();

    // получает текущий экземпляр объекта kDBList
    $object =& $this->GetList($params);

    $o = '';
    $i = 0;
    // метод foreach проходит по массиву Fields и происходит работа с опциями полей
    foreach ($grid_config as $field => $options) {
        $i++;
        // установка параметров блока
        $block_params = Array();
        // имя блока
        $block_params['name'] = $force_block ? $force_block : (isset($options[$mode.'_block']) ? $options[$mode.'_block'] : $def_block);
        // название поля
        $block_params['field'] = $field;
        // устанавливает значения sort_field, если оно есть в опциях этого поля
        $block_params['sort_field'] = isset($options['sort_field']) ? $options['sort_field'] : $field;
        // устанавливает значения filter_field, если оно есть в опциях этого поля
        $block_params['filter_field'] = isset($options['filter_field']) ? $options['filter_field'] : $field;

        // получаем ширину колонки из ColumnPickerHelper
        $w = $picker_helper->GetWidth($field);
        if ($w) $options['width'] = $w;

        // получает из опций текущего поля значение параметра use_phrases
        $field_options = $object->GetFieldOptions($field);
        if (array_key_exists('use_phrases', $field_options)) {
            $block_params['use_phrases'] = $field_options['use_phrases'];
        }
        // устанавливаем значения параметра is_last - последняя ли запись ?
        $block_params['is_last'] = ($i == count($grid_config));
        // объединение всех 3 массивов для параметров блока.
        $block_params = array_merge($std_params, $options, $block_params);
        // вывод текущего поля в блок с параметрами.
        $o.= $this->Application->ParseBlock($block_params, 1);
    }
    return $o;
}

Заметки редактора

текст

коррекция

totals_block, totals

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

selector

Если в качестве значений данного параметра можно передавать не только «checkbox», то их все нужно указать. Они кстати указаны в упомянутой в описании данного параметра статье.

no_special

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

grid_height

Не указано, в чём в данном случае измеряются единицы задания высоты.

no_toolbar, search

Нужно проверить, а работают-ли данные параметры так, как о них написано.

  • Фильтры описывать тут необязательно, т.к. о них уже написана отдельная статья. Желательно использовать картинки фильтров из неё.