|
Компонента списка поддерживает
следующие возможности:
- Отображение
таблицы со списком элементов
- Форматирование
полей элементов при отрисовке
- Поддержка
пагинации
- Установка
количества отображаемых элементов на странице
- Управление
отображаемыми столбцами
- Управление
сортировкой столбцов
- Поддержка
действий (стандартные, собственные, групповые операции)
Создание списка
Для создания компоненты списка
необходимо реализовать:
- Класс
контроллера, наследуемый от AMI_ModListAdm
- Класс
отображения, наследуемый от AMI_ModListView_JSON
Пример классов компонент списка:
class AmiSample_ListAdm extends AMI_ModListAdm{
}
class AmiSample_ListViewAdm extends AMI_ModListView_JSON{
public function __construct(){
$this->tplFileName = '_local/plugins_distr/' . $this->getModId() . '/templates/list.tpl';
parent::__construct();
// Init columns
$this
->addColumnType('id', 'hidden')
->addColumn('nickname')
->addColumn('birth')
->addColumnType('age', 'int')
->setColumnTensility('nickname');
}
protected function getModLocalePath(){
return '_local/plugins_distr/' . $this->getModId() . '/templates/list.lng';
}
}
Описание методов, использованных
в примере, будет приведено ниже.
Определение списка и порядка полей
Метод addColumn используется для добавления полей в список.
Первый метод рекомендуется
использовать непосредственно для добавления полей в список, а второй – для
динамического добавления, т.е. добавления полей в зависимости от условий.
Позиции
Для задания порядка полей
используются позиции (placeholders).
Позиция – это место в
последовательности, относительно которого могут быть размещены элементы
управления и другие позиции. Механизм применяется для того, чтобы создать
единообразие расположения элементов управления.
Позиции бывают 2 видов: позиции
элементов и секции. Секцию следует понимать, как логическую группу элементов.
Секция отличается от позиции элемента тем, что имеет начало и конец.
Для того чтобы задать порядок
полей, необходимо задать порядок позиций при помощи метода putPlaceholder
или addPlaceholders.
Последний метод позволяет производить групповое добавление позиций элементов.
Параметры метода putPlaceholder:
- название
позиции
- место
размещения относительно других позиций
- является
ли позиция секцией
Пример:
$this->putPlaceholder('nickname',
'datefrom.before|seo.begin|form.end');
В данном примере добавляется
позиция nickname по следующему правилу:
- Если
есть позиция datefrom, то новую позицию добавляют перед ней
- Если
позиции datefrom нет, но есть секция seo, то добавляем позицию в ее начало
- Если
ни позиции datefrom нет и нет секции seo, то добавляем позицию в конце формы
Рассмотрим подробнее возможные
относительные положения.
У позиции элемента есть 2
относительных положения для добавления:
- перед
позицией элемента (before)
- после
позиции элемента (after)
В отличие от позиции элемента,
для секции существуют 4 относительных положения для добавления:
- перед
началом секции (before)
- в
начале секции (start)
- в
конце секции (end)
- после
секции (after)
Следует понимать:
- позиция
может быть не используемой, т.е. ей не будет соответствовать элемента
управления
- имя
позиции и секции уникально; при добавлении позиции с именем, которое уже
есть в списке позиций, она будет добавлена
Форматтеры
Форматтер – это метод, преобразовывающий данные из модели
к виду, требуемому для отображения.
Для того чтобы назначить полю списка форматтер, при
формировании списка отображаемых полей в методе getColumns,
необходимо вызвать метод formatColumn.
Пример:
$this->formatColumn('nickname', array($this,
'fmtTruncate'));
Первый параметр – название поля модели, второй – callback. В данный момент
существует один стандартный callback-метод,
описанный в API, он начинается с префикса
fmt: fmtTruncate.
Существует возможность добавления собственных форматтеров.
Пример добавления и прототип для собственных форматтеров приведен в описании
метода formatColumn.
Рекомендуется для собственных форматтеров также использовать префикс fmt.
Действия
В список можно добавлять действия над элементами. Действия
разделяются по типу отображения:
1.
Действия в столбце действий (последний в
списке);
2.
Действия в существующем столбец с данными;
3.
Действия в отдельных столбцах;
4.
Действия в отдельных столбцах, иконка,
всплывающая подсказка и параметры, передаваемые серверу которых зависят от
значения поля типа «флаг».
Действия добавляются следующим образом:
1.
В контроллере списка (наследнике AMI_ModListAdm)
вызываются методы добавления действий;
2.
Описываются обработчики действий в контроллере
действий списка (наследнике AMI_ModListActions);
3.
Заполняются данные для локализации в файле
«templates/list.lng»;
Для отображения графического файла иконки в списке нужно
в папку «img» дистрибутива плагина добавить
png-файл с названиям «icon-{$action}.png».
Групповые действия
В список можно добавлять действия, совершаемые над группой
элементов. Для добавления групповой операции необходимо:
1.
В контроллере списка (наследнике AMI_ModListAdm)
вызываются методы добавления групповых действий;
2.
Описать обработчики действий в контроллере
действий списка (наследнике AMI_ModListGroupActions);
3.
Заполнить данные для локализации в файле
«templates/client.lng»;
4.
4. Для отображения графического файла иконки в списке нужно папку модуля «img» добавить png-файлы размером 24x24 px с названиями «icon-{$action}.png», «icon-grp_{$action}.png».
Примеры реализации
Задача. Есть модель, содержащая 3 свойства: id, nickname, birth. Необходимо создать классы
компонента списка элементов модели, отображающих все 3 эти свойства, nickname необходимо
выводить не более чем 50 символов. В списке необходимо иметь следующие возможности:
открыть элемент на редактирование, удалить эолемент, скопировать элемент.
Должны быть следующие групповые операции: опубликовать,
распубликовать, переименовать и удалить.
class AmiSample_ListAdm extends AMI_ModListAdm{
// Id ресурса контроллера действий спсика
protected $listActionsResId = 'ami_sample/list_actions/controller/adm';
public function init(){
// AMI_ModListAdm::addActions() must be called before parent::init()!
// Добавление действий «Редактировать», «Удалить», «Копировать», «Просмотр» в столбец действий (последний в списке), все перечисленные действия, кроме действия «Просмотр», модифицируют данные моделей, поэтому имеют префикс AMI_ModListAdm::REQUIRE_FULL_ENV
$this->addActions(array(self::REQUIRE_FULL_ENV . 'edit', self::REQUIRE_FULL_ENV . 'delete', self::REQUIRE_FULL_ENV . 'copy', 'show'));
// Добавление групповых действий «Опубликовать», «Распубликовать», «Переименовать», «Удалить»
// Первым элементом массива, описывающего каждое действие
// является имя действия. Все перечисленные действия модифицируют
// данные моделей, поэтому имеют префикс
// AMI_ModListAdm::REQUIRE_FULL_ENV
// Вторым элементом следует позиция действия в списке, механизм
// аналогичен установке позиций полей в списке. Если позиция
// встречается впервые и не содержит точки, оно рассматривается как
// имя секции. Секции разделяются между собой вертикальным
// разделителем.
$this->addGroupActions(
array(
array(self::REQUIRE_FULL_ENV . 'public', 'public_section'),
array(self::REQUIRE_FULL_ENV . 'unpublic', 'public_section'),
array(self::REQUIRE_FULL_ENV . 'rename', 'rename_section'),
array(self::REQUIRE_FULL_ENV . 'delete', 'delete_section'));
parent::init();
return $this;
}
}
class AmiSample_ListActionsAdm extends AMI_ModListActions{
// Обработчик действия «Копировать»
public function dispatchCopy($name, array $aEvent, $handlerModId, $srcModId){
$oItem = $this->getItem($this->getRequestId()));
$nickname = $oItem->nickname;
$newNickname = '- ' . $nickname;
$oItem->nickname = $newNickname;
$oItem->resetId();
$oItem->save();
$aEvent['oResponse']->addStatusMessage(
'status_copied',
array(
'source' => $nickname,
'destination' => $newNickname
)
);
$this->refreshView();
return $aEvent;
}
}
class AmiSample_ListGroupActionsAdm extends AMI_ModListGroupActions{
// Обработчик группового действия «Удалить»
public function dispatchGrpDelete($name, array $aEvent, $handlerModId, $srcModId){
return parent::dispatchGrpDelete($name, $aEvent, $handlerModId, $srcModId);
}
// Обработчик группового действия «Переименовать»
public function dispatchGrpRename($name, array $aEvent, $handlerModId, $srcModId){
$oListActionsAdm = AMI::getResource($handlerModId . '/list_actions/controller/adm');
$aRequestIds = $this->getRequestIds();
foreach($aRequestIds as $id){
// Устанавливаем id элемента для последующего вызова действия «Переименовать»
$aEvent['oRequest']->set('mod_action_id', $id);
// Сохраняем данные события для последующего исполдьзования в контроллере действий списка
$oListActionsAdm->setActionData($name, $aEvent, $handlerModId, $srcModId);
$oListActionsAdm->dispatchRename($name, $aEvent, $handlerModId, $srcModId);
}
// Сбрасывыем все статусные сообщения, которые были добавлены при вызове $oListActionsAdm->dispatchRename()
$aEvent['oResponse']->resetStatusMessages();
// Задаём статусное сообщение с информацией о количестве переименованных элементов
$aEvent['oResponse']->addStatusMessage('status_grp_rename', array('num_items' => sizeof($aRequestIds)));
// Обновление компоненты списка на клиенте после выполнения действия
$this->refreshView();
return $aEvent;
}
}
class AmiSample_ListViewAdm extends AMI_ModListView_JSON{
public function __construct(){
$this->tplFileName = '_local/plugins_distr/' . $this->getModId() . '/templates/list.tpl';
parent::__construct();
// Инициализация столбцов
$this
// добавляем столбцы
->addColumn('id')
->addColumn('nickname')
->addColumn('birth')
// добавляем виртуальный столбец и задаём его тип
->addColumnType('age', 'int')
// задаём автоматическую ширину столбцу «Имя»
->setColumnTensility('nickname')
// задаём столбцы, по которым можно для сортировки
->addSortColumns(
array(
'public',
'nickname',
'birth'
)
);
// Задаём столбцу с действием «Переименовать» место отображения перед столбцом «Имя»
$this->putPlaceholder('rename', 'nickname.before');
// Задаём максимальную длину строки 50 символов для столбца «Имя»
$this->formatColumn(
'nickname',
array($this, 'fmtTruncate'),
array(
'length' => 50
)
);
}
protected function getModLocalePath(){
return '_local/plugins_distr/' . $this->getModId() . '/templates/list.lng';
}
}
Подробное описание логики работы примера в более сложном
виде описано в главе «Пример
реализации модуля».
|