Конструктор списков
Целью создания и использования конструктора списков является минимизация дублирования кода, скорость разработки и простота создания списков и форм сущностей модулей или дополнений.
Список состоит из следующих элементов:
- табы
- фильтры списка
- столбцы списка
- список записей в табличном виде
- постраничная навигация (pagination)
- столбец действий с элементами списка: редактирование, удаление записи и другие
Перейдем к простому примеру создания списка. Рассмотрим упрощенную сущность публикаций (постов в блоге), представленную в базе данных следующим образом:
CREATE TABLE `bff_posts` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(200) NOT NULL DEFAULT '', -- название
`enabled` tinyint(1) unsigned NOT NULL DEFAULT '1', -- включена ли публикация
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, -- дата создания
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Для формирования списка можно выделить несколько логических шагов:
- Cоздаём объект списка
$list
и передаем ему объект контроллера$this
$list = \tplAdmin::blockList($this);
- Задаем столбцы списка
$list->column(ID столбца, Название, Доп. параметры)
.
$list->column('id', 'ID')
->column('title', 'Название')
->column('created', 'Дата создания');
- Добавляем обработчик события переключения состояния записи
onToggle()
.
Необходимо это для возможности указать публикуется ли запись непосредственно из списка.
$list->onToggle(function($id, $type){
# требует необходимого метода в модели,
# выполняющего изменение поля `enabled` для записи по eё $id
$this->model->postToggle($id, $type);
});
Состояние определяет поле enabled
, обязательно должно присутствовать в данных записи, полученных из модели при отрисовке списка (далее в пункте 6).
В обработчик события переключения состояния записи $list->onToggle(callback)
передаем callback, параметрами которого являются:
-
id
идентификатор записи -
type
название поля, по которому происходит переключение состояния записи (в нашем случае и по умолчанию'enabled'
): опубликована 1 / снята с публикации 0
- Добавляем обработчики события удаления записей, для возможности удалить запись непосредственно из списка.
$list->onDelete(function($id) {
# удаляем запись путем вызова соответствующего метода модели
$res = $this->model->postDelete($id);
if ( ! $res) {
$this->errors->impossible();
return;
}
});
Аналогично в обработчик события удаления записи передаем callback, отвечающий за удаление записи. Вторым параметром может передаваться callback,
выполняющий логику перед удалением записи.
- Задаем параметры постраничной навигации списка. Метод
total(count)
позволяет использовать пагинацию по умолчанию (с заданным количеством записей на страницу 20шт). Для этого достаточно сообщить списку общее количество записей, имеющихся в базе данных.
$count = $this->model->postsListingCount(); // получаем этого количество от модели
$list->total($count);
Установить необходимое вам количество записей на странице пагинации можно следующим образом:
$list->perPage(10);
- Получаем записи и добавляем их в список.
Данные о каждой записи в нашем примере должны содержать поля:id, title, created, enabled
В случае если в базе данных поле хранящее состояние публикации имеет другое название, напримерpublicated
, тогда при формировании выборки используем alias'publicated as enabled'
.
$rows = $this->model->postsListing($filter); // получаем данные от модели
$list->rows($rows);
- Для вывода списка используем метод
view
, результатом котого будет итоговая HTML страница списка.
Метод контроллера должен вернуть этот результат приложению.
return $list->view();
В качестве примера использования все логические шаги объединены в метод админ-контроллера отвечающий за формирование списка:
/**
* Пример метода админ-контроллера модуля/дополнения
* формирующего список публикаций
* @return string HTML
*/
public function listing()
{
# создаем объект списка
$list = \tplAdmin::blockList($this);
# задаем табы для списка
# для возможности фильтрации по статусу публикации
$list->tabs()
->add(0, 'Все')
->add(1, 'Опубликованные')
->add(2, 'Неопубликованные');
# задаем столбцы списка
$list
->column('id', 'ID', 80)
->column('title', 'Название', false, [
'align' => $list::COLUMN_ALIGN_LEFT, # выравниваем по левому краю
])
->column('created', 'Дата создания', 130)
;
# добавляем действие переключения состояния записи
$list->onToggle(function($id, $type){
$this->model->postToggle($id, $type);
});
# добавляем действие удаления записи
$list->onDelete(function($id) {
if ( ! $id) {
$this->errors->impossible();
return;
}
# получаем данные о записи по $id
$data = $this->model->postData($id);
if (empty($data)) {
$this->errors->impossible();
return;
}
# удаляем запись
$res = $this->model->postDelete($id);
if ( ! $res) {
$this->errors->impossible();
return;
}
});
# формируем фильтр выборки и порядок сортировки по табу
$orderBy = 'id';
$filter = [];
switch ($list->tab()) {
case 0: # Все
# Сортировка по умолчанию
break;
case 1: # Опубликованные
$filter['enabled'] = 1;
break;
case 2: # Неопубликованные
$filter['enabled'] = 0;
break;
}
# постраничная навигация (по умолчанию 20 записей на странице)
$list->perPage(10); # устанавливаем кол-во записей на странице в значение 10
$list->perPageRange([10 => '10', -1 => 'Все']); # фомируем доступные варианты выбора кол-ва
$list->total($this->model->postsListingCount($filter)); # запрашиваем общее кол-во у модели
# получаем данные о записях
$rows = $this->model->postsListing($filter, $orderBy);
$list->rows($rows);
# отрисовываем список и возвращаем его приложению
return $list->view();
}
Формирование списка в отдельном шаблоне
Обычно формирование списка выносят в отдельный шаблон поскольку табов и столбцов может быть больше, а также могут добавиться фильтры списка.
В таком случае при создании объекта списка используют второй параметр:
$list = \tplAdmin::blockList($objectController, 'listing');
В котором указывает название php шаблона tpl/listing.php контроллера модуля/дополнения где и выполняется инициализация всех элементов списка. Внутри шаблона объект списка будет доступен в виде локальной переменной $list
, а объект контроллера как $this
.
<?php
/**
* @var $list \bff\tpl\admin\BlockList
*/
$list->column('id', 'ID', 80)
->column('title', 'Название');
// ...
Список и формы
Для обработки событий добавления и редактирования записи следует использовать компонент Формы. Подробнее о порядке применения форм в списках читайте в данной статье.
Ротация
За включение ротации (перемещение записей выше/ниже путем перетягивания) отвечает обработчик события ротации onRotate()
.
Обычно сортировку записей выполняют в определенном табе списка. Для осуществления такой сортировки необходимо:
- наличие поля в базе данных, отвечающего за положение записи в общем списке, обычно в базе данных это поле числового типа:
`num` int(11) unsigned DEFAULT '0',
- при задании тaбов укажите дополнительный атрибут ротации в настройках таба вот таким образом:
# задаем табы для списка
$list->tabs()
->add(0, 'Все')
->add(1, 'Избранные', true, ['rotate' => true]); # таб с включенной ротацией
- Добавьте обработчик события ротации
$list->onRotate(callback)
, который принимает callback отвечающий за ротацию записей:
$list->onRotate(function($tab_id){
$this->model->db->rotateTablednd(`bff_posts`, '', 'id', 'num');
});
- Выполнить сортировку записей можно предусмотренным для этого стандартным методом
rotateTablednd()
, параметрами которого являются название таблицы -bff_posts
, дополнительные параметры SQL запроса -''
, название поля id записи -id
, название поля, по которому осуществляется сортировка -num
. - Задайте параметры сортировки при выводе полей необходимого таба:
switch ($list->tab()) {
case 0: # Все
# Сортировка по умолчанию
break;
case 1: # Избранные
$orderBy = 'num'; # сортировка по полю num
break;
}
- Если необходимо выполнять ротацию в пределах определенной выборки, нужно указать дополнительные параметры запроса для функции
rotateTablednd()
в виде SQL условия:
$this->model->db->rotateTablednd(`bff_posts`, 'AND status = 1', 'id', 'num');
В таком случае важно также учитывать, что поле num
в таблице должно присваиваться при создании новой записи с учетом данного условия выборки.
Избранные записи
Метод onToggle()
может принимать в качестве второго параметра значение 'fav'
. В этом случае переключатель будет иметь вид добавления в избранное.
Поле в базе данных также должно называться 'fav'
.
$list->onToggle(function($id, $type){
# вызываем метод модели для изменения значения поля `fav` записи по eё $id
$this->model->postToggle($id, $type);
}, 'fav');
Динамические свойства
В списках доступно подключение компонента динамических свойств.
Подключение выполняется при помощи метода onDynprops(dynpropsObject)
, параметром является объект компонента динамических свойств.
Кнопка управления динамическими свойствами записи появляется в столбце "Действие".