Shared rss feeds:

Servare Mentem - blog

Мой предыдущий блог

четверг, 15 мая 2008 г.

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]

<< Главная страница

-->