SM PHP Toolkit : part2
Сегодня я поведаю о втором довольно удобном приспособлении, вошедшем в SMPHPToolkit. Это грид вообще (и ajax-грид в частности). К примеру, необходимо реализовать на странице грид с пэйджингом, сортировками и без перегрузки страницы. Для начала, предположим что у нас есть класс уровня доступа к данным:
// Данные для отображения
class mydata{
private static $mydata = array(
array(0,'Название 1'),
array(1,'Название 2'),
array(2,'Название 3'),
array(3,'Название 4'),
array(4,'Название 5'),
array(5,'Название 6'),
array(6,'Название 7'),
array(7,'Название 8'),
array(8,'Название 9'),
);
// функция получения общего числа записей
public static function get_total(){return count(self::$mydata);}
// функция получения определённой страницы отсортированных данных
// cортировка указывается третьим параметром (true=ASC,false=DESC)
public static function get_page($pagesize, $page, $asc = true){
return array_slice(
($asc)?self::$mydata:array_reverse(self::$mydata),
($page-1)*$pagesize, $pagesize);
}
// так же допустим есть функция удаления строки
public static function delete($num){unset(self::$mydata[$num]);}
}
Начнём создавать грид. Сперва инициализируем AJAX-буфер, а так же AJAX-EntitiesManager - класс, который позволит упростить работу с действиями над данными в гриде. Для буфера зададим отображение прогресса (будет отображаться модальное окно с надписью "wait please"). В качестве второго аргумента для $emanager зададим созданный буфер.
// Инициализируем буфер и менеджер сущностей
$ajaxbuffer = new ajax_buffer("ajax_buffer");
$ajaxbuffer->show_progress(true);
$emanager = new ajax_entities_manager('entities_manager', $ajaxbuffer);
Теперь посмотрим на код инициализации грида:
$grid = new ajax_grid('my_grid',$datasource,$ajaxbuffer,$grid_pager);
В качестве аргументов он принимает datasource (объект данных для отрисовки), ajax-буфер и используемый пейджер. Буфер и пейджер - аргументы необязательные. При этом если не задать первый - он будет создан внутри грида автоматически.
Пейджер представляет собой набор кнопок для переключения страниц а так же алгоритм пересчёта общего числа страниц и вычисления текущей страницы. В качестве аргументов он принимает общее число записей которые будут отображаться в гриде и размер страницы.
$grid_pager = new ajax_grid_pager('my_grid_pager',mydata::get_total(),5);
Объект-источник данных (DataSource) для грида описывает его заголовок и задаёт данные. Однако, при создании грида достаточно того, чтобы источник данных содержал только описание колонок. Каждая колонка принимает несколько параметров: имя поля, отображаемое имя поля, тип поля и флаг указывающий на то возможна ли сортировка по данному полю. Дополнительным параметром может служить объект расширяющий объект grid_formatter. Он нужен для кастомизированного отображения данных.
$datasource = new grid_data_source(new grid_header_item_array(
new grid_header_item('id','Id',type::STRING, true),
new grid_header_item('title','Заголовок',type::STRING, true),
new grid_header_item('actions','Действия',null, false, new my_grid_formatter('actions', $emanager->client_id()))
));
А вот так можно перегрузить форматтер для того чтобы отрисовать кастом-поле "Действия":
class my_grid_formatter extends grid_formatter {
protected $_field = '';
protected $_client_id = '';
public function __construct($field, $client_id){
$this->_field = $field;
$this->_client_id = $client_id;
}
public function format($data, $type, $number = 0, $columns = null)
{
switch($this->_field){
case 'actions':
return '<a href="javascript:'.$this->_client_id.
'.deleteItem('.$data[0].');">Удалить</a>';
default:
return parent::format($data,$type);
}
}
};
Прежде чем выбирать данные и передавать их источнику, нужно их изменить (ведь, возможно данная страница уже запрошена по ajax и пользователь нажал, к примеру "удалить" какую-то запись. Проверим.
// Если нужно выполнить какие-то действия над данными по постбэку
if($ajaxbuffer->is_post_back() && $emanager->isAnyAction())
{
switch($emanager->getAction())
{
// необходимо удалить строку
case $emanager->action->DEL:
mydata::delete($emanager->getItem());
break;
}
// сбрасываем действие (в противном случае оно будет активно при каждом ajax запросе)
$emanager->eraseAction();
}
Вот и всё. Все основные инициализации сделаны. Теперь нужно выбрать данные и передать их источнику.
// выбираем текущую страницу отсортированных данных
$mydata = mydata::get_page($grid_pager->get_pagesize(),$grid_pager->get_curpage(), $grid->get_sort_direction() != sorting::SORT_DIR_DESC);
// добавляем данные в DataSource
foreach($mydata as $data)
{
$datasource->add_row(array($data[0],$data[1],$data));
}
Остаётся только отрендерить страницу. Для этого удобно воспользоваться шаблонизатором - классом templater, так же входящим в SMPHPToolkit. Ему передаётся путь к шаблону и ассоциативный массив переменных, которые будут доступны в шаблоне.
// Выводим результат
$templater = new templater(dirname(__FILE__).'/templates/main.tpl.php');
die($templater->render(array('grid'=>$grid,
'ajaxbuffer'=>$ajaxbuffer,
'title'=>'Тестовая страница',
)));
Ниже приведён код шаблона.
<html>
<head>
<title><?=$title ?></title>
<link href="css/grid.css" rel="stylesheet" type="text/css"/>
<link href="css/ajax.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="js/common/prototype.js"></script>
<script type="text/javascript" src="js/common/scriptaculous.js"></script>
<script type="text/javascript" src="js/common/window/window.js"></script>
<script type="text/javascript" src="js/smphptoolkit/ajaxbuffer.js"></script>
<script type="text/javascript" src="js/smphptoolkit/entitymanager.js"></script>
</head>
<body>
<? $ajaxbuffer->start(); ?>
<?=$grid->render(); ?><br/>
Updated at: <?=date("H:i:s") ?>
<? $ajaxbuffer->end(); ?>
</body>
</html>

В итоге получили симпатичный грид с пейджингом, сортировкой и возможностью удалить строку. И всё это работает через ассинхронные запросы к серверу. Изменив mydata, к примеру, на обращение к mysql, можно элементарно поменять данные на данные из базы, а чтобы добавить колонку, достаточно добавить элемент в массивы которые передаются источнику данных. Чтобы поменять шаблон - достаточно исправить строку, передаваемую шаблонизатору. Всё строится примитивно, интуитивно понятно и в то же время достаточно гибко.
Код данного примера и последнюю версию smphptoolkit можно забрать в моём svn.
В следующем посте про SMPHPToolkit я расскажу про класс storage, который позволяет оптимально хранить данные в текстовых файлах и удобно работать с выборками данных.
Комментарии: 0:
Отправить комментарий
Подпишитесь на каналы Комментарии к сообщению [Atom]
<< Главная страница