Skip to content
This repository
Browse code

ENHANCEMENT Release of DataGridPagination

This class extends the DataGridPresenter with the behaviour and looks of a paginated Datagrid.
  • Loading branch information...
commit 83e90aaafed72e2d59b3dbf9b5a26a4dca3348c2 1 parent cf408d7
Stig Lindqvist authored October 27, 2011
3  css/GridFieldPaginator.css
... ...
@@ -0,0 +1,3 @@
  1
+.ss-gridfield-pagination { text-align: center; padding-bottom: 10px; }
  2
+
  3
+.ss-gridfield-pagination-button.loading { background: url(../images/network-save.gif) no-repeat 0% 50%; padding-left: 20px; }
66  forms/GridField.php
... ...
@@ -1,7 +1,25 @@
1 1
 <?php
2 2
 /**
3 3
  * Displays a {@link SS_List} in a grid format.
4  
- *
  4
+ * 
  5
+ * GridFIeld is a field that takes an SS_List and displays it in an table with rows 
  6
+ * and columns. It reminds of the old TableFields but works with SS_List types 
  7
+ * and only loads the necessary rows from the list.
  8
+ * 
  9
+ * The minimum configuration is to pass in name and title of the field and a 
  10
+ * SS_List.
  11
+ * 
  12
+ * <code>
  13
+ * $gridField = new GridField('ExampleGrid', 'Example grid', new DataList('Page'));
  14
+ * </code>
  15
+ * 
  16
+ * If you want to modify the output of the grid you can attach a customised 
  17
+ * DataGridPresenter that are the actual Renderer of the data. Sapphire provides
  18
+ * a default one if you chooses not to.
  19
+ * 
  20
+ * @see GridFieldPresenter
  21
+ * @see SS_List
  22
+ * 
5 23
  * @package sapphire
6 24
  * @subpackage forms
7 25
  */
@@ -10,7 +28,7 @@ class GridField extends FormField {
10 28
 	/**
11 29
 	 * @var SS_List
12 30
 	 */
13  
-	protected $dataSource = null;
  31
+	protected $list = null;
14 32
 	
15 33
 	/**
16 34
 	 * @var string
@@ -26,27 +44,44 @@ class GridField extends FormField {
26 44
 	 * @var string - the classname of the DataObject that the GridField will display
27 45
 	 */
28 46
 	protected $modelClassName = '';
29  
-
  47
+	
  48
+	/**
  49
+	 * Url handlers
  50
+	 *
  51
+	 * @var array
  52
+	 */
  53
+	public static $url_handlers = array(
  54
+		'$Action' => '$Action',
  55
+	);
  56
+	
30 57
 	/**
31 58
 	 * Creates a new GridField field
32 59
 	 *
33 60
 	 * @param string $name
34 61
 	 * @param string $title
35  
-	 * @param SS_List $datasource
  62
+	 * @param SS_List $dataList
36 63
 	 * @param Form $form 
37  
-	 * @param string $dataPresenterClassName
  64
+	 * @param string|GridFieldPresenter $dataPresenterClassName - can either pass in a string or an instance of a GridFieldPresenter
38 65
 	 */
39  
-	public function __construct($name, $title = null, SS_List $datasource = null, Form $form = null, $dataPresenterClassName = 'GridFieldPresenter') {
  66
+	public function __construct($name, $title = null, SS_List $dataList = null, Form $form = null, $dataPresenterClassName = 'GridFieldPresenter') {
40 67
 		parent::__construct($name, $title, null, $form);
41 68
 		
42  
-		if ($datasource) {
43  
-			$this->setDatasource($datasource);
  69
+		if ($dataList) {
  70
+			$this->setList($dataList);
44 71
 		}
45 72
 		
46 73
 		$this->setPresenter($dataPresenterClassName);
47 74
 	}
48 75
 	
49 76
 	/**
  77
+	 *
  78
+	 * @return string - HTML
  79
+	 */
  80
+	public function index() {
  81
+		return $this->FieldHolder();
  82
+	}
  83
+
  84
+	/**
50 85
 	 * @param string $modelClassName 
51 86
 	 */
52 87
 	public function setModelClass($modelClassName) {
@@ -63,8 +98,8 @@ public function getModelClass() {
63 98
 		if ($this->modelClassName) {
64 99
 			return $this->modelClassName;
65 100
 		}
66  
-		if ($this->datasource->dataClass) {
67  
-			return $this->datasource->dataClass;
  101
+		if ($this->list->dataClass) {
  102
+			return $this->list->dataClass;
68 103
 		}
69 104
 		
70 105
 		throw new Exception(get_class($this).' does not have a modelClassName');
@@ -113,11 +148,10 @@ public function getPresenter(){
113 148
 	/**
114 149
 	 * Set the datasource
115 150
 	 *
116  
-	 * @param SS_List $datasource
  151
+	 * @param SS_List $list
117 152
 	 */
118  
-	public function setDataSource(SS_List $datasource) {
119  
-		$this->datasource = $datasource;
120  
-		
  153
+	public function setList(SS_List $list) {
  154
+		$this->list = $list;
121 155
 		return $this;
122 156
 	}
123 157
 
@@ -126,8 +160,8 @@ public function setDataSource(SS_List $datasource) {
126 160
 	 *
127 161
 	 * @return SS_List
128 162
 	 */
129  
-	public function getDataSource() {
130  
-		return $this->datasource;
  163
+	public function getList() {
  164
+		return $this->list;
131 165
 	}
132 166
 	
133 167
 	/**
277  forms/GridFieldPaginator.php
... ...
@@ -0,0 +1,277 @@
  1
+<?php
  2
+/**
  3
+ * GridFieldPaginator decorates the GridFieldPresenter with the possibility to
  4
+ * paginate the GridField.
  5
+ * 
  6
+ * @see GridField
  7
+ * @see GridFieldPresenter
  8
+ * @package sapphire
  9
+ */
  10
+class GridFieldPaginator extends ViewableData {
  11
+	
  12
+	/**
  13
+	 *
  14
+	 * @var string
  15
+	 */
  16
+	protected $template = 'GridFieldPaginator';
  17
+	
  18
+	/**
  19
+	 *
  20
+	 * @var int
  21
+	 */
  22
+	protected $totalNumberOfPages = 0;
  23
+	
  24
+	/**
  25
+	 *
  26
+	 * @var int
  27
+	 */
  28
+	protected $currentPage = 0;
  29
+	
  30
+	/**
  31
+	 *
  32
+	 * @param int $totalNumberOfPages
  33
+	 * @param int $currentPage 
  34
+	 */
  35
+	public function __construct($totalNumberOfPages,$currentPage = 1) {
  36
+		Requirements::javascript('sapphire/javascript/GridFieldPaginator.js');
  37
+		$this->totalNumberOfPages = $totalNumberOfPages;
  38
+		$this->currentPage = $currentPage;
  39
+	}
  40
+	
  41
+	/**
  42
+	 * Returns the rendered template for GridField
  43
+	 *
  44
+	 * @return string 
  45
+	 */
  46
+	public function Render() {
  47
+		return $this->renderWith(array($this->template));
  48
+	}
  49
+	
  50
+	/**
  51
+	 * Returns a url to the last page in the result
  52
+	 *
  53
+	 * @return string 
  54
+	 */
  55
+	public function FirstLink() {
  56
+		if($this->haveNoPages()) {
  57
+			return false;
  58
+		}
  59
+		return 1;
  60
+	}
  61
+	
  62
+	/**
  63
+	 * Returns a url to the previous page in the result
  64
+	 *
  65
+	 * @return string 
  66
+	 */
  67
+	public function PreviousLink() {
  68
+		if($this->isFirstPage() || $this->haveNoPages()) {
  69
+			return false;
  70
+		}
  71
+		// Out of bounds
  72
+		if($this->currentPage>$this->totalNumberOfPages){
  73
+			return $this->LastLink();
  74
+		}
  75
+		
  76
+		return ($this->currentPage-1);
  77
+	}
  78
+	
  79
+	/**
  80
+	 * Returns a list of pages with links, pagenumber and if it is the current 
  81
+	 * page.
  82
+	 *
  83
+	 * @return ArrayList 
  84
+	 */
  85
+	public function Pages() {
  86
+		if($this->haveNoPages()) {
  87
+			return false;
  88
+		}
  89
+		
  90
+		$list = new ArrayList();
  91
+		for($idx=1;$idx<=$this->totalNumberOfPages;$idx++) {
  92
+			$data = new ArrayData(array());
  93
+			$data->setField('PageNumber',$idx);
  94
+			if($idx == $this->currentPage ) {
  95
+				$data->setField('Current',true);
  96
+			} else {
  97
+				$data->setField('Current',false);
  98
+			}
  99
+			
  100
+			$data->setField('Link',$idx);
  101
+			$list->push($data);	
  102
+		}
  103
+		return $list;
  104
+	}
  105
+	
  106
+	/**
  107
+	 * Returns a url to the next page in the result
  108
+	 *
  109
+	 * @return string 
  110
+	 */
  111
+	public function NextLink() {
  112
+		if($this->isLastPage() || $this->haveNoPages() ) {
  113
+			return false;
  114
+		}
  115
+		// Out of bounds
  116
+		if($this->currentPage<1) {
  117
+			return $this->FirstLink();
  118
+		}
  119
+		return ($this->currentPage+1);
  120
+	}
  121
+	
  122
+	/**
  123
+	 * Returns a url to the last page in the result
  124
+	 *
  125
+	 * @return string 
  126
+	 */
  127
+	public function LastLink() {
  128
+		if($this->haveNoPages()) {
  129
+			return false;
  130
+		}
  131
+		return ($this->totalNumberOfPages);
  132
+	}
  133
+	
  134
+	/**
  135
+	 * Are we currently on the first page
  136
+	 *
  137
+	 * @return bool 
  138
+	 */
  139
+	protected function isFirstPage() {
  140
+		return (bool)($this->currentPage<=1);
  141
+	}
  142
+	
  143
+	/**
  144
+	 * Are we currently on the last page?
  145
+	 *
  146
+	 * @return bool 
  147
+	 */
  148
+	protected function isLastPage() {
  149
+		return (bool)($this->currentPage>=$this->totalNumberOfPages);
  150
+	}
  151
+	
  152
+	/**
  153
+	 * Is there only one page of results?
  154
+	 *
  155
+	 * @return bool 
  156
+	 */
  157
+	protected function haveNoPages() {
  158
+		return (bool)($this->totalNumberOfPages<=1);
  159
+	}
  160
+	
  161
+}
  162
+
  163
+/**
  164
+ * This is the extension that decorates the GridFieldPresenter. Since a extension
  165
+ * can't be a Viewable data it's split like this.
  166
+ * 
  167
+ * @see GridField
  168
+ * @package sapphire
  169
+ */
  170
+class GridFieldPaginator_Extension extends Extension {
  171
+	
  172
+	/**
  173
+	 *
  174
+	 * @var int
  175
+	 */
  176
+	protected $paginationLimit;
  177
+	
  178
+	/**
  179
+	 *
  180
+	 * @var int
  181
+	 */
  182
+	protected $totalNumberOfPages = 1;
  183
+	
  184
+	/**
  185
+	 *
  186
+	 * @var int
  187
+	 */
  188
+	protected $currentPage = 1;
  189
+	
  190
+	/**
  191
+	 *
  192
+	 * @return string 
  193
+	 */
  194
+	public function Footer() {
  195
+		return new GridFieldPaginator($this->totalNumberOfPages, $this->currentPage);
  196
+	}
  197
+	
  198
+	/**
  199
+	 * NOP
  200
+	 */
  201
+	public function __construct() {}
  202
+	
  203
+	/**
  204
+	 * Set the limit for each page
  205
+	 *
  206
+	 * @param int $limit
  207
+	 * @return GridFieldPaginator_Extension 
  208
+	 */
  209
+	public function paginationLimit($limit) {
  210
+		$this->paginationLimit = $limit;
  211
+		return $this;
  212
+	}
  213
+	
  214
+	/**
  215
+	 * Filter the list to only contain a pagelength of items
  216
+	 * 
  217
+	 * @return bool - if the pagination was activated
  218
+	 * @see GridFieldPresenter::Items()
  219
+	 */
  220
+	public function filterList(SS_List $list, $parameters){
  221
+		if(!$this->canUsePagination($list)) {
  222
+			return false;
  223
+		}
  224
+		
  225
+		$currentPage = $parameters->Request->requestVar('page');
  226
+		if(!$currentPage) {
  227
+			$currentPage = 1;
  228
+		}
  229
+		
  230
+		$this->totalNumberOfPages = $this->getMaxPagesCount($list);
  231
+		
  232
+		if($currentPage<1) {
  233
+			// Current page is below 1, show nothing and save cpu cycles
  234
+			$list->where('1=0');
  235
+		} elseif($currentPage > $this->totalNumberOfPages) {
  236
+			// current page is over max pages, show nothing and save cpu cycles
  237
+			$list->where('1=0');
  238
+		} else {
  239
+			$offset = ($currentPage-1)*$this->paginationLimit;
  240
+			$list->getRange((int)$offset,$this->paginationLimit);
  241
+		}
  242
+		$this->currentPage = $currentPage;
  243
+		
  244
+		return true;
  245
+	}
  246
+	
  247
+	/**
  248
+	 * Helper function that see if the pagination has been set and that the 
  249
+	 * $list can use pagination.
  250
+	 *
  251
+	 * @param SS_List $list
  252
+	 * @return bool
  253
+	 */
  254
+	protected function canUsePagination(SS_List $list) {
  255
+		if(!$this->paginationLimit) {
  256
+			return false;
  257
+		}
  258
+		if(!method_exists($list, 'getRange')) {
  259
+			return false;
  260
+		}
  261
+		if(!method_exists($list, 'limit')){
  262
+			return false;
  263
+		}
  264
+		return true;
  265
+	}
  266
+	
  267
+	/**
  268
+	 *
  269
+	 * @return int 
  270
+	 */
  271
+	protected function getMaxPagesCount($list) {
  272
+		$list->limit(null);
  273
+		$number = $list->count();
  274
+		$number = ceil($number/$this->paginationLimit);
  275
+		return $number;
  276
+	}
  277
+}
120  forms/GridFieldPresenter.php
... ...
@@ -1,7 +1,46 @@
1 1
 <?php
2  
-
3 2
 /**
  3
+ * The GridFieldPresenter is responsible for rendering and attach user behaviour
  4
+ * to a GridField.
  5
+ * 
  6
+ * You can create a GridFieldPresenter and inject that into a GridField to 
  7
+ * customise look and feel of GridField.
  8
+ * 
  9
+ * It also have the possibility to let extensions to modify the look and feel of
  10
+ * the GridField if you dont want to make a fully blown GridFieldPresenter.
  11
+ * 
  12
+ * In the following example we configure the GridField to sort the DataList in 
  13
+ * the GridField by Title. This will override the sorting on the DataList.
  14
+ * 
  15
+ * <code>
  16
+ * $presenter = new GridFieldPresenter();
  17
+ * $presenter->sort('Title', 'desc');
  18
+ * $gridField = new GridField('ExampleGrid', 'Example grid', new DataList('Page'),null, $presenter);
  19
+ * </code>
  20
+ * 
  21
+ * Another example is to change the template for the rendering 
  22
+ *
  23
+ * <code>
  24
+ * $presenter = new GridFieldPresenter();
  25
+ * $presenter->setTemplate('MyNiftyGridTemplate');
  26
+ * $gridField = new GridField('ExampleGrid', 'Example grid', new DataList('Page'),null, $presenter);
  27
+ * </code>
  28
+ * 
  29
+ * There is also a possibility to add extensions to the GridPresenter. An 
  30
+ * example is the DataGridPagination that decorates the GridField with 
  31
+ * pagination. Look in the GridFieldPresenter::Items() and the filterList extend
  32
+ * and GridFieldPresenter::Footers()
  33
+ * 
  34
+ * <code>
  35
+ * GridFieldPresenter::add_extension('GridFieldPaginator_Extension');
  36
+ * $presenter = new GridFieldPresenter();
  37
+ * // This is actually calling GridFieldPaginator_Extension::paginationLimit()
  38
+ * $presenter->paginationLimit(3);
  39
+ * $gridField = new GridField('ExampleGrid', 'Example grid', new DataList('Page'),null, $presenter);
  40
+ * </code>
  41
+ * 
4 42
  * @see GridField
  43
+ * @see GridFieldPaginator
5 44
  * @package sapphire
6 45
  */
7 46
 class GridFieldPresenter extends ViewableData {
@@ -46,11 +85,20 @@ class GridFieldPresenter extends ViewableData {
46 85
 	/**
47 86
 	 * @param string $template 
48 87
 	 */
49  
-	function setTemplate($template){
  88
+	public function setTemplate($template){
50 89
 		$this->template = $template;
51 90
 	}
52 91
 	
53 92
 	/**
  93
+	 * The name of the Field
  94
+	 *
  95
+	 * @return string
  96
+	 */
  97
+	public function Name() {
  98
+		return $this->getGridField()->Name();
  99
+	}
  100
+	
  101
+	/**
54 102
 	 * @param GridField $GridField 
55 103
 	 */
56 104
 	public function setGridField(GridField $grid){
@@ -65,6 +113,14 @@ public function getGridField(){
65 113
 	}
66 114
 	
67 115
 	/**
  116
+	 *
  117
+	 * @param type $extension 
  118
+	 */
  119
+	public static function add_extension($extension) {
  120
+		parent::add_extension(__CLASS__, $extension);
  121
+	}
  122
+	
  123
+	/**
68 124
 	 * Sort the grid by columns
69 125
 	 *
70 126
 	 * @param string $column
@@ -82,27 +138,29 @@ public function sort($column, $direction = 'asc') {
82 138
 	 * @return ArrayList
83 139
 	 */
84 140
 	public function Items() {
85  
-		$items = new ArrayList();
  141
+	$items = new ArrayList();
86 142
 		
87 143
 		if($this->sorting) {
88  
-			$this->setSorting($this->sorting);
  144
+			$this->setSortingOnList($this->sorting);
89 145
 		}
  146
+		//empty for now
  147
+		$list = $this->getGridField()->getList();
  148
+		
  149
+		$parameters = new stdClass();
  150
+		$parameters->Controller = Controller::curr();
  151
+		$parameters->Request = Controller::curr()->getRequest();
90 152
 		
91  
-		if($sources = $this->getGridField()->getDataSource()) {
  153
+		$this->extend('filterList', $list, $parameters);
  154
+	
  155
+		if($list) {
  156
+			$numberOfRows = $list->count();
92 157
 			$counter = 0;
93  
-			
94  
-			foreach($sources as $source) {
95  
-				if(!$source) {
96  
-					continue;
97  
-				}
98  
-				
99  
-				$itemPresenter = new $this->itemClass($source, $this);
100  
-				$itemPresenter->iteratorProperties($counter++, $sources->count());
101  
-				
  158
+			foreach($list as $item) {
  159
+				$itemPresenter = new $this->itemClass($item, $this);
  160
+				$itemPresenter->iteratorProperties($counter++, $numberOfRows);
102 161
 				$items->push($itemPresenter);
103 162
 			}
104 163
 		}
105  
-		
106 164
 		return $items;
107 165
 	}
108 166
 	
@@ -122,22 +180,32 @@ public function Items() {
122 180
 	 * @throws Exception
123 181
 	 */
124 182
 	public function Headers() {
125  
-		if(!$this->getDatasource()) {
  183
+		if(!$this->getList()) {
126 184
 			throw new Exception(sprintf(
127 185
 				'%s needs an data source to be able to render the form', get_class($this->getGridField())
128 186
 			));
129 187
 		}
130  
-		
131  
-		$summaryFields = singleton($this->getModelClass())->summaryFields();
132  
-		
133  
-		return $this->summaryFieldsToList($summaryFields);
  188
+		return $this->summaryFieldsToList($this->FieldList());
  189
+	}
  190
+	
  191
+	/**
  192
+	 *
  193
+	 * @return ArrayList 
  194
+	 */
  195
+	public function Footers() {
  196
+		$arrayList = new ArrayList();
  197
+		$footers = $this->extend('Footer');
  198
+		foreach($footers as $footer) {
  199
+			$arrayList->push($footer);
  200
+		}
  201
+		return $arrayList;
134 202
 	}
135 203
 	
136 204
 	/**
137 205
 	 * @return SS_List
138 206
 	 */
139  
-	protected function getDataSource() {
140  
-		return $this->getGridField()->getDatasource();
  207
+	public function getList() {
  208
+		return $this->getGridField()->getList();
141 209
 	}
142 210
 	
143 211
 	/**
@@ -150,12 +218,12 @@ protected function getModelClass() {
150 218
 	/**
151 219
 	 * Add the combined sorting on the datasource
152 220
 	 * 
153  
-	 * If the sorting isn't set in one go on the datasource, only the latest sort
154  
-	 * will be executed.s
  221
+	 * If the sorting isn't set in the datasource, only the latest sort
  222
+	 * will be executed.
155 223
 	 *
156 224
 	 * @param array $sortColumns 
157 225
 	 */
158  
-	protected function setSorting(array $sortColumns) {
  226
+	protected function setSortingOnList(array $sortColumns) {
159 227
 		$resultColumns = array();
160 228
 		
161 229
 		foreach($sortColumns as $column => $sortOrder) {
@@ -163,7 +231,7 @@ protected function setSorting(array $sortColumns) {
163 231
 		}
164 232
 		
165 233
 		$sort = implode(', ', $resultColumns);
166  
-		$this->getDataSource()->sort($sort);
  234
+		$this->getList()->sort($sort);
167 235
 	}
168 236
 	
169 237
 	/**
30  javascript/GridFieldPaginator.js
... ...
@@ -0,0 +1,30 @@
  1
+jQuery(function($){
  2
+		
  3
+	var onGridClick = function(){
  4
+		var form = $(this).closest("form");
  5
+		var gridField = $(this).closest(".ss-gridfield");
  6
+		$(this).addClass('loading');
  7
+		$.ajax({
  8
+			type: "POST",
  9
+			url: form.attr('action')+'/field/'+gridField.attr('id'),
  10
+			data: form.serialize()+"&page="+$(this).attr('value'), 
  11
+			success: function(data) {
  12
+				$(gridField).replaceWith(data);
  13
+				gridInit();
  14
+			},
  15
+			error: function() {
  16
+				alert('There seems like there where some failure when trying to fetch the page, please reload and try again.');
  17
+			}
  18
+			
  19
+		});
  20
+
  21
+		return false;
  22
+	}
  23
+	
  24
+	var gridInit = function() {
  25
+		$('.ss-gridfield-pagination-button').click(onGridClick);
  26
+	}
  27
+	
  28
+	gridInit();
  29
+	
  30
+});
10  model/DataQuery.php
@@ -298,13 +298,9 @@ function sort($sort) {
298 298
 	 * Set the limit of this query
299 299
 	 */
300 300
 	function limit($limit) {
301  
-		if($limit) {
302  
-			$clone = $this;
303  
-			$clone->query->limit($limit);
304  
-			return $clone;
305  
-		} else {
306  
-			return $this;
307  
-		}
  301
+		$clone = $this;
  302
+		$clone->query->limit($limit);
  303
+		return $clone;
308 304
 	}
309 305
 
310 306
 	/**
7  scss/GridFieldPaginator.scss
... ...
@@ -0,0 +1,7 @@
  1
+.ss-gridfield-pagination { 
  2
+	text-align: center; 
  3
+	padding-bottom: 10px;
  4
+}
  5
+.ss-gridfield-pagination-button.loading{ 
  6
+	background: url(../images/network-save.gif) no-repeat 0% 50%; padding-left: 20px;
  7
+}
2  templates/GridField.ss
... ...
@@ -1,7 +1,7 @@
1 1
 <% require css(sapphire/thirdparty/jquery-ui-themes/smoothness/jquery-ui.css) %>
2 2
 <% require css(sapphire/css/GridField.css) %>
3 3
 
4  
-<div class="ss-gridfield ui-state-default">
  4
+<div class="ss-gridfield ui-state-default" id="$Name">
5 5
 	<table>
6 6
 		<thead>
7 7
 			<tr>
29  templates/GridFieldPaginator.ss
... ...
@@ -0,0 +1,29 @@
  1
+<% require css(sapphire/css/GridFieldPaginator.css) %>
  2
+
  3
+<% if Pages %>
  4
+<div class="ss-gridfield-pagination">
  5
+	<% if FirstLink %> 
  6
+	<button class="ss-gridfield-pagination-button" type="submit" name="page" value="$FirstLink">First</button>
  7
+	<% end_if %> 
  8
+	
  9
+	<% if PreviousLink %>
  10
+	<button class="ss-gridfield-pagination-button" type="submit" name="page" value="$PreviousLink">Previous page</button>
  11
+	<% end_if %> 
  12
+	
  13
+	<% control Pages %>
  14
+		<% if Current %>
  15
+			$PageNumber
  16
+		<% else %>
  17
+		<button class="ss-gridfield-pagination-button" type="submit" name="page" value="$PageNumber">$PageNumber</button>
  18
+		<% end_if %>
  19
+	<% end_control%>
  20
+	
  21
+	<% if NextLink %>
  22
+	<button class="ss-gridfield-pagination-button" type="submit" name="page" value="$NextLink">Next Page</button>
  23
+	<% end_if %> 
  24
+	
  25
+	<% if LastLink %>
  26
+	<button class="ss-gridfield-pagination-button" type="submit" name="page" value="$LastLink">Last</button>
  27
+	<% end_if %> 
  28
+</div>
  29
+<% end_if %> 
10  templates/GridFieldPresenter.ss
... ...
@@ -1,7 +1,7 @@
1 1
 <% require css(sapphire/thirdparty/jquery-ui-themes/smoothness/jquery-ui.css) %>
2 2
 <% require css(sapphire/css/GridField.css) %>
3 3
 
4  
-<div class="ss-gridfield ui-state-default">
  4
+<div class="ss-gridfield ui-state-default" id="$Name">
5 5
 	<table>
6 6
 		<thead>
7 7
 			<tr>
@@ -19,7 +19,11 @@
19 19
 		</tbody>
20 20
 		
21 21
 		<tfoot>
22  
-
23 22
 		</tfoot>
24 23
 	</table>
25  
-</div>
  24
+	
  25
+	<% control Footers %>
  26
+		$Render
  27
+	<% end_control %>
  28
+	
  29
+</div>
2  templates/Includes/GridField_Item.ss
... ...
@@ -1,4 +1,4 @@
1  
-<tr class="ss-gridfield-{$EvenOdd}">
  1
+<tr class="ss-gridfield-{$EvenOdd} $FirstLast">
2 2
 	<% control Fields %>
3 3
 	<td <% if FirstLast %>class="ss-gridfield-{$FirstLast}"<% end_if %>>$Value</td>
4 4
 	<% end_control %>
2  tests/forms/GridFieldFunctionalTest.php
@@ -38,7 +38,7 @@ function Link($action = null) {
38 38
 	public function index() {
39 39
 		$grid = new GridField('testgrid');
40 40
 		$dataSource = DataList::create("GridFieldTest_Person")->sort("Name");
41  
-		$grid->setDataSource($dataSource);
  41
+		$grid->setList($dataSource);
42 42
 		$form = new Form($this, 'gridform', new FieldList($grid), new FieldList(new FormAction('rerender', 'rerender')));
43 43
 		return array('Form'=>$form);
44 44
 	}
38  tests/forms/GridFieldPaginatorTest.php
... ...
@@ -0,0 +1,38 @@
  1
+<?php
  2
+/**
  3
+ * @package sapphire
  4
+ * @subpackage tests
  5
+ */
  6
+class GridFieldPaginatorTest extends SapphireTest {
  7
+
  8
+	/**
  9
+	 *
  10
+	 * @var string
  11
+	 */
  12
+	public static $fixture_file = 'sapphire/tests/forms/GridFieldTest.yml';
  13
+	
  14
+	/**
  15
+	 *
  16
+	 * @var array
  17
+	 */
  18
+	protected $extraDataObjects = array(
  19
+		'GridFieldTest_Person',
  20
+	);
  21
+	
  22
+	public function testGetInstance() {
  23
+		$this->assertTrue(new GridFieldPaginator(1,1) instanceof GridFieldPaginator, 'Trying to find an instance of GridFieldPaginator');
  24
+		$this->assertTrue(new GridFieldPaginator_Extension() instanceof GridFieldPaginator_Extension, 'Trying to find an instance of GridFieldPaginator_Extension');
  25
+	}
  26
+	
  27
+	public function testFlowThroughGridFieldExtension() {
  28
+		$list = new DataList('GridFieldTest_Person');
  29
+		$t = new GridFieldPaginator_Extension();
  30
+		$t->paginationLimit(5);
  31
+		
  32
+		$parameters = new stdClass();
  33
+		$parameters->Request = new SS_HTTPRequest('GET', '/a/url', array('page'=>1));
  34
+		
  35
+		$t->filterList($list, $parameters);
  36
+		$this->assertTrue($t->Footer() instanceof GridFieldPaginator);
  37
+	}
  38
+}
6  tests/forms/GridFieldTest.php
@@ -27,8 +27,8 @@ public function testGetInstance() {
27 27
 	public function testSetDataSource() {
28 28
 		$grid = new GridField('Testgrid');
29 29
 		$source = new ArrayList();
30  
-		$grid->setDatasource($source);
31  
-		$this->assertEquals($source, $grid->getDatasource());
  30
+		$grid->setList($source);
  31
+		$this->assertEquals($source, $grid->getList());
32 32
 	}
33 33
 	
34 34
 	function testSetEmptyDataPresenter() {
@@ -76,7 +76,7 @@ function testFieldHolderWithoutDataSource() {
76 76
 	 */
77 77
 	function testFieldHolder() {
78 78
 		$grid = new GridField('Testgrid');
79  
-		$grid->setDatasource(new DataList('GridFieldTest_Person'));
  79
+		$grid->setList(new DataList('GridFieldTest_Person'));
80 80
 		$this->assertNotNull($grid->FieldHolder());
81 81
 	}
82 82
 }

0 notes on commit 83e90aa

Ingo Schommer

We're using i18n for all core JavaScript through the _t() function, could you add that and ensure that sapphire/javascript/i18n.js and javascript/lang/en_US.js are loaded with the paginator? :)

Stig Lindqvist

Certainly, thanks for reminding an old backend monkey to make proper javascript translations as well.

Please sign in to comment.
Something went wrong with that request. Please try again.