mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge pull request #82 from silverstripe-scienceninjas/release/gridfield-pagination
ENHANCEMENT Release of DataGridPagination
This commit is contained in:
commit
244f0707b1
3
css/GridFieldPaginator.css
Normal file
3
css/GridFieldPaginator.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.ss-gridfield-pagination { text-align: center; padding-bottom: 10px; }
|
||||||
|
|
||||||
|
.ss-gridfield-pagination-button.loading { background: url(../images/network-save.gif) no-repeat 0% 50%; padding-left: 20px; }
|
@ -1,7 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Displays a {@link SS_List} in a grid format.
|
* Displays a {@link SS_List} in a grid format.
|
||||||
*
|
*
|
||||||
|
* GridFIeld is a field that takes an SS_List and displays it in an table with rows
|
||||||
|
* and columns. It reminds of the old TableFields but works with SS_List types
|
||||||
|
* and only loads the necessary rows from the list.
|
||||||
|
*
|
||||||
|
* The minimum configuration is to pass in name and title of the field and a
|
||||||
|
* SS_List.
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* $gridField = new GridField('ExampleGrid', 'Example grid', new DataList('Page'));
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* If you want to modify the output of the grid you can attach a customised
|
||||||
|
* DataGridPresenter that are the actual Renderer of the data. Sapphire provides
|
||||||
|
* a default one if you chooses not to.
|
||||||
|
*
|
||||||
|
* @see GridFieldPresenter
|
||||||
|
* @see SS_List
|
||||||
|
*
|
||||||
* @package sapphire
|
* @package sapphire
|
||||||
* @subpackage forms
|
* @subpackage forms
|
||||||
*/
|
*/
|
||||||
@ -10,7 +28,7 @@ class GridField extends FormField {
|
|||||||
/**
|
/**
|
||||||
* @var SS_List
|
* @var SS_List
|
||||||
*/
|
*/
|
||||||
protected $dataSource = null;
|
protected $list = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
@ -26,26 +44,43 @@ class GridField extends FormField {
|
|||||||
* @var string - the classname of the DataObject that the GridField will display
|
* @var string - the classname of the DataObject that the GridField will display
|
||||||
*/
|
*/
|
||||||
protected $modelClassName = '';
|
protected $modelClassName = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Url handlers
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $url_handlers = array(
|
||||||
|
'$Action' => '$Action',
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new GridField field
|
* Creates a new GridField field
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param string $title
|
* @param string $title
|
||||||
* @param SS_List $datasource
|
* @param SS_List $dataList
|
||||||
* @param Form $form
|
* @param Form $form
|
||||||
* @param string $dataPresenterClassName
|
* @param string|GridFieldPresenter $dataPresenterClassName - can either pass in a string or an instance of a GridFieldPresenter
|
||||||
*/
|
*/
|
||||||
public function __construct($name, $title = null, SS_List $datasource = null, Form $form = null, $dataPresenterClassName = 'GridFieldPresenter') {
|
public function __construct($name, $title = null, SS_List $dataList = null, Form $form = null, $dataPresenterClassName = 'GridFieldPresenter') {
|
||||||
parent::__construct($name, $title, null, $form);
|
parent::__construct($name, $title, null, $form);
|
||||||
|
|
||||||
if ($datasource) {
|
if ($dataList) {
|
||||||
$this->setDatasource($datasource);
|
$this->setList($dataList);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setPresenter($dataPresenterClassName);
|
$this->setPresenter($dataPresenterClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return string - HTML
|
||||||
|
*/
|
||||||
|
public function index() {
|
||||||
|
return $this->FieldHolder();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $modelClassName
|
* @param string $modelClassName
|
||||||
*/
|
*/
|
||||||
@ -63,8 +98,8 @@ class GridField extends FormField {
|
|||||||
if ($this->modelClassName) {
|
if ($this->modelClassName) {
|
||||||
return $this->modelClassName;
|
return $this->modelClassName;
|
||||||
}
|
}
|
||||||
if ($this->datasource->dataClass) {
|
if ($this->list->dataClass) {
|
||||||
return $this->datasource->dataClass;
|
return $this->list->dataClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Exception(get_class($this).' does not have a modelClassName');
|
throw new Exception(get_class($this).' does not have a modelClassName');
|
||||||
@ -113,11 +148,10 @@ class GridField extends FormField {
|
|||||||
/**
|
/**
|
||||||
* Set the datasource
|
* Set the datasource
|
||||||
*
|
*
|
||||||
* @param SS_List $datasource
|
* @param SS_List $list
|
||||||
*/
|
*/
|
||||||
public function setDataSource(SS_List $datasource) {
|
public function setList(SS_List $list) {
|
||||||
$this->datasource = $datasource;
|
$this->list = $list;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,8 +160,8 @@ class GridField extends FormField {
|
|||||||
*
|
*
|
||||||
* @return SS_List
|
* @return SS_List
|
||||||
*/
|
*/
|
||||||
public function getDataSource() {
|
public function getList() {
|
||||||
return $this->datasource;
|
return $this->list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
277
forms/GridFieldPaginator.php
Normal file
277
forms/GridFieldPaginator.php
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* GridFieldPaginator decorates the GridFieldPresenter with the possibility to
|
||||||
|
* paginate the GridField.
|
||||||
|
*
|
||||||
|
* @see GridField
|
||||||
|
* @see GridFieldPresenter
|
||||||
|
* @package sapphire
|
||||||
|
*/
|
||||||
|
class GridFieldPaginator extends ViewableData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $template = 'GridFieldPaginator';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $totalNumberOfPages = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $currentPage = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param int $totalNumberOfPages
|
||||||
|
* @param int $currentPage
|
||||||
|
*/
|
||||||
|
public function __construct($totalNumberOfPages,$currentPage = 1) {
|
||||||
|
Requirements::javascript('sapphire/javascript/GridFieldPaginator.js');
|
||||||
|
$this->totalNumberOfPages = $totalNumberOfPages;
|
||||||
|
$this->currentPage = $currentPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the rendered template for GridField
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function Render() {
|
||||||
|
return $this->renderWith(array($this->template));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a url to the last page in the result
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function FirstLink() {
|
||||||
|
if($this->haveNoPages()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a url to the previous page in the result
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function PreviousLink() {
|
||||||
|
if($this->isFirstPage() || $this->haveNoPages()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Out of bounds
|
||||||
|
if($this->currentPage>$this->totalNumberOfPages){
|
||||||
|
return $this->LastLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($this->currentPage-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of pages with links, pagenumber and if it is the current
|
||||||
|
* page.
|
||||||
|
*
|
||||||
|
* @return ArrayList
|
||||||
|
*/
|
||||||
|
public function Pages() {
|
||||||
|
if($this->haveNoPages()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$list = new ArrayList();
|
||||||
|
for($idx=1;$idx<=$this->totalNumberOfPages;$idx++) {
|
||||||
|
$data = new ArrayData(array());
|
||||||
|
$data->setField('PageNumber',$idx);
|
||||||
|
if($idx == $this->currentPage ) {
|
||||||
|
$data->setField('Current',true);
|
||||||
|
} else {
|
||||||
|
$data->setField('Current',false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data->setField('Link',$idx);
|
||||||
|
$list->push($data);
|
||||||
|
}
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a url to the next page in the result
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function NextLink() {
|
||||||
|
if($this->isLastPage() || $this->haveNoPages() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Out of bounds
|
||||||
|
if($this->currentPage<1) {
|
||||||
|
return $this->FirstLink();
|
||||||
|
}
|
||||||
|
return ($this->currentPage+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a url to the last page in the result
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function LastLink() {
|
||||||
|
if($this->haveNoPages()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ($this->totalNumberOfPages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we currently on the first page
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function isFirstPage() {
|
||||||
|
return (bool)($this->currentPage<=1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we currently on the last page?
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function isLastPage() {
|
||||||
|
return (bool)($this->currentPage>=$this->totalNumberOfPages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is there only one page of results?
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function haveNoPages() {
|
||||||
|
return (bool)($this->totalNumberOfPages<=1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the extension that decorates the GridFieldPresenter. Since a extension
|
||||||
|
* can't be a Viewable data it's split like this.
|
||||||
|
*
|
||||||
|
* @see GridField
|
||||||
|
* @package sapphire
|
||||||
|
*/
|
||||||
|
class GridFieldPaginator_Extension extends Extension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $paginationLimit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $totalNumberOfPages = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $currentPage = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function Footer() {
|
||||||
|
return new GridFieldPaginator($this->totalNumberOfPages, $this->currentPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NOP
|
||||||
|
*/
|
||||||
|
public function __construct() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the limit for each page
|
||||||
|
*
|
||||||
|
* @param int $limit
|
||||||
|
* @return GridFieldPaginator_Extension
|
||||||
|
*/
|
||||||
|
public function paginationLimit($limit) {
|
||||||
|
$this->paginationLimit = $limit;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter the list to only contain a pagelength of items
|
||||||
|
*
|
||||||
|
* @return bool - if the pagination was activated
|
||||||
|
* @see GridFieldPresenter::Items()
|
||||||
|
*/
|
||||||
|
public function filterList(SS_List $list, $parameters){
|
||||||
|
if(!$this->canUsePagination($list)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentPage = $parameters->Request->requestVar('page');
|
||||||
|
if(!$currentPage) {
|
||||||
|
$currentPage = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->totalNumberOfPages = $this->getMaxPagesCount($list);
|
||||||
|
|
||||||
|
if($currentPage<1) {
|
||||||
|
// Current page is below 1, show nothing and save cpu cycles
|
||||||
|
$list->where('1=0');
|
||||||
|
} elseif($currentPage > $this->totalNumberOfPages) {
|
||||||
|
// current page is over max pages, show nothing and save cpu cycles
|
||||||
|
$list->where('1=0');
|
||||||
|
} else {
|
||||||
|
$offset = ($currentPage-1)*$this->paginationLimit;
|
||||||
|
$list->getRange((int)$offset,$this->paginationLimit);
|
||||||
|
}
|
||||||
|
$this->currentPage = $currentPage;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function that see if the pagination has been set and that the
|
||||||
|
* $list can use pagination.
|
||||||
|
*
|
||||||
|
* @param SS_List $list
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function canUsePagination(SS_List $list) {
|
||||||
|
if(!$this->paginationLimit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!method_exists($list, 'getRange')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!method_exists($list, 'limit')){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function getMaxPagesCount($list) {
|
||||||
|
$list->limit(null);
|
||||||
|
$number = $list->count();
|
||||||
|
$number = ceil($number/$this->paginationLimit);
|
||||||
|
return $number;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,46 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* The GridFieldPresenter is responsible for rendering and attach user behaviour
|
||||||
|
* to a GridField.
|
||||||
|
*
|
||||||
|
* You can create a GridFieldPresenter and inject that into a GridField to
|
||||||
|
* customise look and feel of GridField.
|
||||||
|
*
|
||||||
|
* It also have the possibility to let extensions to modify the look and feel of
|
||||||
|
* the GridField if you dont want to make a fully blown GridFieldPresenter.
|
||||||
|
*
|
||||||
|
* In the following example we configure the GridField to sort the DataList in
|
||||||
|
* the GridField by Title. This will override the sorting on the DataList.
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* $presenter = new GridFieldPresenter();
|
||||||
|
* $presenter->sort('Title', 'desc');
|
||||||
|
* $gridField = new GridField('ExampleGrid', 'Example grid', new DataList('Page'),null, $presenter);
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* Another example is to change the template for the rendering
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* $presenter = new GridFieldPresenter();
|
||||||
|
* $presenter->setTemplate('MyNiftyGridTemplate');
|
||||||
|
* $gridField = new GridField('ExampleGrid', 'Example grid', new DataList('Page'),null, $presenter);
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
|
* There is also a possibility to add extensions to the GridPresenter. An
|
||||||
|
* example is the DataGridPagination that decorates the GridField with
|
||||||
|
* pagination. Look in the GridFieldPresenter::Items() and the filterList extend
|
||||||
|
* and GridFieldPresenter::Footers()
|
||||||
|
*
|
||||||
|
* <code>
|
||||||
|
* GridFieldPresenter::add_extension('GridFieldPaginator_Extension');
|
||||||
|
* $presenter = new GridFieldPresenter();
|
||||||
|
* // This is actually calling GridFieldPaginator_Extension::paginationLimit()
|
||||||
|
* $presenter->paginationLimit(3);
|
||||||
|
* $gridField = new GridField('ExampleGrid', 'Example grid', new DataList('Page'),null, $presenter);
|
||||||
|
* </code>
|
||||||
|
*
|
||||||
* @see GridField
|
* @see GridField
|
||||||
|
* @see GridFieldPaginator
|
||||||
* @package sapphire
|
* @package sapphire
|
||||||
*/
|
*/
|
||||||
class GridFieldPresenter extends ViewableData {
|
class GridFieldPresenter extends ViewableData {
|
||||||
@ -46,10 +85,19 @@ class GridFieldPresenter extends ViewableData {
|
|||||||
/**
|
/**
|
||||||
* @param string $template
|
* @param string $template
|
||||||
*/
|
*/
|
||||||
function setTemplate($template){
|
public function setTemplate($template){
|
||||||
$this->template = $template;
|
$this->template = $template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the Field
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function Name() {
|
||||||
|
return $this->getGridField()->Name();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param GridField $GridField
|
* @param GridField $GridField
|
||||||
*/
|
*/
|
||||||
@ -64,6 +112,14 @@ class GridFieldPresenter extends ViewableData {
|
|||||||
return $this->GridField;
|
return $this->GridField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param type $extension
|
||||||
|
*/
|
||||||
|
public static function add_extension($extension) {
|
||||||
|
parent::add_extension(__CLASS__, $extension);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort the grid by columns
|
* Sort the grid by columns
|
||||||
*
|
*
|
||||||
@ -82,27 +138,29 @@ class GridFieldPresenter extends ViewableData {
|
|||||||
* @return ArrayList
|
* @return ArrayList
|
||||||
*/
|
*/
|
||||||
public function Items() {
|
public function Items() {
|
||||||
$items = new ArrayList();
|
$items = new ArrayList();
|
||||||
|
|
||||||
if($this->sorting) {
|
if($this->sorting) {
|
||||||
$this->setSorting($this->sorting);
|
$this->setSortingOnList($this->sorting);
|
||||||
}
|
}
|
||||||
|
//empty for now
|
||||||
|
$list = $this->getGridField()->getList();
|
||||||
|
|
||||||
if($sources = $this->getGridField()->getDataSource()) {
|
$parameters = new stdClass();
|
||||||
|
$parameters->Controller = Controller::curr();
|
||||||
|
$parameters->Request = Controller::curr()->getRequest();
|
||||||
|
|
||||||
|
$this->extend('filterList', $list, $parameters);
|
||||||
|
|
||||||
|
if($list) {
|
||||||
|
$numberOfRows = $list->count();
|
||||||
$counter = 0;
|
$counter = 0;
|
||||||
|
foreach($list as $item) {
|
||||||
foreach($sources as $source) {
|
$itemPresenter = new $this->itemClass($item, $this);
|
||||||
if(!$source) {
|
$itemPresenter->iteratorProperties($counter++, $numberOfRows);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$itemPresenter = new $this->itemClass($source, $this);
|
|
||||||
$itemPresenter->iteratorProperties($counter++, $sources->count());
|
|
||||||
|
|
||||||
$items->push($itemPresenter);
|
$items->push($itemPresenter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,22 +180,32 @@ class GridFieldPresenter extends ViewableData {
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function Headers() {
|
public function Headers() {
|
||||||
if(!$this->getDatasource()) {
|
if(!$this->getList()) {
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
'%s needs an data source to be able to render the form', get_class($this->getGridField())
|
'%s needs an data source to be able to render the form', get_class($this->getGridField())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
return $this->summaryFieldsToList($this->FieldList());
|
||||||
$summaryFields = singleton($this->getModelClass())->summaryFields();
|
}
|
||||||
|
|
||||||
return $this->summaryFieldsToList($summaryFields);
|
/**
|
||||||
|
*
|
||||||
|
* @return ArrayList
|
||||||
|
*/
|
||||||
|
public function Footers() {
|
||||||
|
$arrayList = new ArrayList();
|
||||||
|
$footers = $this->extend('Footer');
|
||||||
|
foreach($footers as $footer) {
|
||||||
|
$arrayList->push($footer);
|
||||||
|
}
|
||||||
|
return $arrayList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return SS_List
|
* @return SS_List
|
||||||
*/
|
*/
|
||||||
protected function getDataSource() {
|
public function getList() {
|
||||||
return $this->getGridField()->getDatasource();
|
return $this->getGridField()->getList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,12 +218,12 @@ class GridFieldPresenter extends ViewableData {
|
|||||||
/**
|
/**
|
||||||
* Add the combined sorting on the datasource
|
* Add the combined sorting on the datasource
|
||||||
*
|
*
|
||||||
* If the sorting isn't set in one go on the datasource, only the latest sort
|
* If the sorting isn't set in the datasource, only the latest sort
|
||||||
* will be executed.s
|
* will be executed.
|
||||||
*
|
*
|
||||||
* @param array $sortColumns
|
* @param array $sortColumns
|
||||||
*/
|
*/
|
||||||
protected function setSorting(array $sortColumns) {
|
protected function setSortingOnList(array $sortColumns) {
|
||||||
$resultColumns = array();
|
$resultColumns = array();
|
||||||
|
|
||||||
foreach($sortColumns as $column => $sortOrder) {
|
foreach($sortColumns as $column => $sortOrder) {
|
||||||
@ -163,7 +231,7 @@ class GridFieldPresenter extends ViewableData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sort = implode(', ', $resultColumns);
|
$sort = implode(', ', $resultColumns);
|
||||||
$this->getDataSource()->sort($sort);
|
$this->getList()->sort($sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
30
javascript/GridFieldPaginator.js
Normal file
30
javascript/GridFieldPaginator.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
jQuery(function($){
|
||||||
|
|
||||||
|
var onGridClick = function(){
|
||||||
|
var form = $(this).closest("form");
|
||||||
|
var gridField = $(this).closest(".ss-gridfield");
|
||||||
|
$(this).addClass('loading');
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: form.attr('action')+'/field/'+gridField.attr('id'),
|
||||||
|
data: form.serialize()+"&page="+$(this).attr('value'),
|
||||||
|
success: function(data) {
|
||||||
|
$(gridField).replaceWith(data);
|
||||||
|
gridInit();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
alert('There seems like there where some failure when trying to fetch the page, please reload and try again.');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var gridInit = function() {
|
||||||
|
$('.ss-gridfield-pagination-button').click(onGridClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
gridInit();
|
||||||
|
|
||||||
|
});
|
@ -298,13 +298,9 @@ class DataQuery {
|
|||||||
* Set the limit of this query
|
* Set the limit of this query
|
||||||
*/
|
*/
|
||||||
function limit($limit) {
|
function limit($limit) {
|
||||||
if($limit) {
|
$clone = $this;
|
||||||
$clone = $this;
|
$clone->query->limit($limit);
|
||||||
$clone->query->limit($limit);
|
return $clone;
|
||||||
return $clone;
|
|
||||||
} else {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
7
scss/GridFieldPaginator.scss
Normal file
7
scss/GridFieldPaginator.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.ss-gridfield-pagination {
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
.ss-gridfield-pagination-button.loading{
|
||||||
|
background: url(../images/network-save.gif) no-repeat 0% 50%; padding-left: 20px;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<% require css(sapphire/thirdparty/jquery-ui-themes/smoothness/jquery-ui.css) %>
|
<% require css(sapphire/thirdparty/jquery-ui-themes/smoothness/jquery-ui.css) %>
|
||||||
<% require css(sapphire/css/GridField.css) %>
|
<% require css(sapphire/css/GridField.css) %>
|
||||||
|
|
||||||
<div class="ss-gridfield ui-state-default">
|
<div class="ss-gridfield ui-state-default" id="$Name">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
29
templates/GridFieldPaginator.ss
Normal file
29
templates/GridFieldPaginator.ss
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<% require css(sapphire/css/GridFieldPaginator.css) %>
|
||||||
|
|
||||||
|
<% if Pages %>
|
||||||
|
<div class="ss-gridfield-pagination">
|
||||||
|
<% if FirstLink %>
|
||||||
|
<button class="ss-gridfield-pagination-button" type="submit" name="page" value="$FirstLink">First</button>
|
||||||
|
<% end_if %>
|
||||||
|
|
||||||
|
<% if PreviousLink %>
|
||||||
|
<button class="ss-gridfield-pagination-button" type="submit" name="page" value="$PreviousLink">Previous page</button>
|
||||||
|
<% end_if %>
|
||||||
|
|
||||||
|
<% control Pages %>
|
||||||
|
<% if Current %>
|
||||||
|
$PageNumber
|
||||||
|
<% else %>
|
||||||
|
<button class="ss-gridfield-pagination-button" type="submit" name="page" value="$PageNumber">$PageNumber</button>
|
||||||
|
<% end_if %>
|
||||||
|
<% end_control%>
|
||||||
|
|
||||||
|
<% if NextLink %>
|
||||||
|
<button class="ss-gridfield-pagination-button" type="submit" name="page" value="$NextLink">Next Page</button>
|
||||||
|
<% end_if %>
|
||||||
|
|
||||||
|
<% if LastLink %>
|
||||||
|
<button class="ss-gridfield-pagination-button" type="submit" name="page" value="$LastLink">Last</button>
|
||||||
|
<% end_if %>
|
||||||
|
</div>
|
||||||
|
<% end_if %>
|
@ -1,7 +1,7 @@
|
|||||||
<% require css(sapphire/thirdparty/jquery-ui-themes/smoothness/jquery-ui.css) %>
|
<% require css(sapphire/thirdparty/jquery-ui-themes/smoothness/jquery-ui.css) %>
|
||||||
<% require css(sapphire/css/GridField.css) %>
|
<% require css(sapphire/css/GridField.css) %>
|
||||||
|
|
||||||
<div class="ss-gridfield ui-state-default">
|
<div class="ss-gridfield ui-state-default" id="$Name">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -19,7 +19,11 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
|
|
||||||
<tfoot>
|
<tfoot>
|
||||||
|
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
|
||||||
|
<% control Footers %>
|
||||||
|
$Render
|
||||||
|
<% end_control %>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<tr class="ss-gridfield-{$EvenOdd}">
|
<tr class="ss-gridfield-{$EvenOdd} $FirstLast">
|
||||||
<% control Fields %>
|
<% control Fields %>
|
||||||
<td <% if FirstLast %>class="ss-gridfield-{$FirstLast}"<% end_if %>>$Value</td>
|
<td <% if FirstLast %>class="ss-gridfield-{$FirstLast}"<% end_if %>>$Value</td>
|
||||||
<% end_control %>
|
<% end_control %>
|
||||||
|
@ -38,7 +38,7 @@ class GridFieldFunctionalTest_Controller extends Controller {
|
|||||||
public function index() {
|
public function index() {
|
||||||
$grid = new GridField('testgrid');
|
$grid = new GridField('testgrid');
|
||||||
$dataSource = DataList::create("GridFieldTest_Person")->sort("Name");
|
$dataSource = DataList::create("GridFieldTest_Person")->sort("Name");
|
||||||
$grid->setDataSource($dataSource);
|
$grid->setList($dataSource);
|
||||||
$form = new Form($this, 'gridform', new FieldList($grid), new FieldList(new FormAction('rerender', 'rerender')));
|
$form = new Form($this, 'gridform', new FieldList($grid), new FieldList(new FormAction('rerender', 'rerender')));
|
||||||
return array('Form'=>$form);
|
return array('Form'=>$form);
|
||||||
}
|
}
|
||||||
|
38
tests/forms/GridFieldPaginatorTest.php
Normal file
38
tests/forms/GridFieldPaginatorTest.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package sapphire
|
||||||
|
* @subpackage tests
|
||||||
|
*/
|
||||||
|
class GridFieldPaginatorTest extends SapphireTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public static $fixture_file = 'sapphire/tests/forms/GridFieldTest.yml';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $extraDataObjects = array(
|
||||||
|
'GridFieldTest_Person',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function testGetInstance() {
|
||||||
|
$this->assertTrue(new GridFieldPaginator(1,1) instanceof GridFieldPaginator, 'Trying to find an instance of GridFieldPaginator');
|
||||||
|
$this->assertTrue(new GridFieldPaginator_Extension() instanceof GridFieldPaginator_Extension, 'Trying to find an instance of GridFieldPaginator_Extension');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFlowThroughGridFieldExtension() {
|
||||||
|
$list = new DataList('GridFieldTest_Person');
|
||||||
|
$t = new GridFieldPaginator_Extension();
|
||||||
|
$t->paginationLimit(5);
|
||||||
|
|
||||||
|
$parameters = new stdClass();
|
||||||
|
$parameters->Request = new SS_HTTPRequest('GET', '/a/url', array('page'=>1));
|
||||||
|
|
||||||
|
$t->filterList($list, $parameters);
|
||||||
|
$this->assertTrue($t->Footer() instanceof GridFieldPaginator);
|
||||||
|
}
|
||||||
|
}
|
@ -27,8 +27,8 @@ class GridFieldTest extends SapphireTest {
|
|||||||
public function testSetDataSource() {
|
public function testSetDataSource() {
|
||||||
$grid = new GridField('Testgrid');
|
$grid = new GridField('Testgrid');
|
||||||
$source = new ArrayList();
|
$source = new ArrayList();
|
||||||
$grid->setDatasource($source);
|
$grid->setList($source);
|
||||||
$this->assertEquals($source, $grid->getDatasource());
|
$this->assertEquals($source, $grid->getList());
|
||||||
}
|
}
|
||||||
|
|
||||||
function testSetEmptyDataPresenter() {
|
function testSetEmptyDataPresenter() {
|
||||||
@ -76,7 +76,7 @@ class GridFieldTest extends SapphireTest {
|
|||||||
*/
|
*/
|
||||||
function testFieldHolder() {
|
function testFieldHolder() {
|
||||||
$grid = new GridField('Testgrid');
|
$grid = new GridField('Testgrid');
|
||||||
$grid->setDatasource(new DataList('GridFieldTest_Person'));
|
$grid->setList(new DataList('GridFieldTest_Person'));
|
||||||
$this->assertNotNull($grid->FieldHolder());
|
$this->assertNotNull($grid->FieldHolder());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user