Permalink
Browse files

NEW: GridFieldPageCount control for displaying the current page count…

…/total in the gridview header. Designed to complement a functional pager in the grid footer.

NEW: GridFieldPageCount widget to default config settings
FIX: @extend .col_buttons in GridField.scss which was raising a warning
  • Loading branch information...
1 parent b22a7af commit f265595c1eb93edc0461280c9b666e59b3d489da @tractorcow tractorcow committed with sminnee Sep 25, 2012
View

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -142,6 +142,7 @@ public function __construct($itemsPerPage=null) {
$this->addComponent($sort = new GridFieldSortableHeader());
$this->addComponent($filter = new GridFieldFilterHeader());
$this->addComponent(new GridFieldDataColumns());
+ $this->addComponent(new GridFieldPageCount('toolbar-header-right'));
$this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
$sort->setThrowExceptionOnBadDataType(false);
@@ -182,6 +183,7 @@ public function __construct($itemsPerPage=null) {
$this->addComponent(new GridFieldDataColumns());
$this->addComponent(new GridFieldEditButton());
$this->addComponent(new GridFieldDeleteAction());
+ $this->addComponent(new GridFieldPageCount('toolbar-header-right'));
$this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
$this->addComponent(new GridFieldDetailForm());
@@ -222,6 +224,7 @@ public function __construct($itemsPerPage=null) {
$this->addComponent(new GridFieldDataColumns());
$this->addComponent(new GridFieldEditButton());
$this->addComponent(new GridFieldDeleteAction());
+ $this->addComponent(new GridFieldPageCount('toolbar-header-right'));
$this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
$this->addComponent(new GridFieldDetailForm());
@@ -0,0 +1,47 @@
+<?php
+
+/**
+ * GridFieldPage displays a simple current page count summary.
+ * E.g. "View 1 - 15 of 32"
+ *
+ * Depends on GridFieldPaginator being added to the same gridfield
+ *
+ * @package framework
+ * @subpackage fields-relational
+ */
+class GridFieldPageCount implements GridField_HTMLProvider {
+ /**
+ * @var string placement indicator for this control
+ */
+ protected $targetFragment;
+
+ /**
+ * Which template to use for rendering
+ *
+ * @var string
+ */
+ protected $itemClass = 'GridFieldPageCount';
+
+ /**
+ * @param string $targetFrament The fragment indicating the placement of this page count
+ */
+ public function __construct($targetFragment = 'before') {
+ $this->targetFragment = $targetFragment;
+ }
+
+ /**
+ * @param GridField $gridField
+ * @return array
+ */
+ public function getHTMLFragments($gridField) {
+
+ // Retrieve paging parameters from the directing paginator component
+ $paginator = $gridField->getConfig()->getComponentByType('GridFieldPaginator');
+ if ($paginator && ($forTemplate = $paginator->getTemplateParameters($gridField))) {
+ return array(
+ $this->targetFragment => $forTemplate->renderWith($this->itemClass)
+ );
+ }
+ }
+
+}
@@ -7,8 +7,8 @@
* @subpackage fields-relational
*/
class GridFieldPaginator implements GridField_HTMLProvider, GridField_DataManipulator, GridField_ActionProvider {
+
/**
- *
* @var int
*/
protected $itemsPerPage = 15;
@@ -94,11 +94,26 @@ public function handleAction(GridField $gridField, $actionName, $arguments, $dat
if($actionName !== 'paginate') {
return;
}
- $state = $gridField->State->GridFieldPaginator;
+ $state = $this->getGridPagerState($gridField);
$state->currentPage = (int)$arguments;
}
protected $totalItems = 0;
+
+ /**
+ * Retrieves/Sets up the state object used to store and retrieve information
+ * about the current paging details of this GridField
+ * @param GridField $gridField
+ * @return GridState_Data
+ */
+ protected function getGridPagerState(GridField $gridField) {
+ $state = $gridField->State->GridFieldPaginator;
+
+ // Force the state to the initial page if none is set
+ if(empty($state->currentPage)) $state->currentPage = 1;
+
+ return $state;
+ }
/**
*
@@ -107,40 +122,47 @@ public function handleAction(GridField $gridField, $actionName, $arguments, $dat
* @return SS_List
*/
public function getManipulatedData(GridField $gridField, SS_List $dataList) {
+
if(!$this->checkDataType($dataList)) return $dataList;
- $this->totalItems = $dataList->count();
+ $state = $this->getGridPagerState($gridField);
- $state = $gridField->State->GridFieldPaginator;
- if(!is_int($state->currentPage)) {
- $state->currentPage = 1;
- }
+ // Update item count prior to filter. GridFieldPageCount will rely on this value
+ $this->totalItems = $dataList->count();
if(!($dataList instanceof SS_Limitable)) {
return $dataList;
}
- if(!$state->currentPage) {
- return $dataList->limit((int)$this->itemsPerPage);
- }
+
$startRow = $this->itemsPerPage * ($state->currentPage - 1);
return $dataList->limit((int)$this->itemsPerPage, (int)$startRow);
}
-
+
/**
- *
- * @param GridField $gridField
- * @return array
+ * Determines arguments to be passed to the template for building this field
+ * @return ArrayData|null If paging is available this will be an ArrayData
+ * object of paging details with these parameters:
+ * <ul>
+ * <li>OnlyOnePage: boolean - Is there only one page?</li>
+ * <li>FirstShownRecord: integer - Number of the first record displayed</li>
+ * <li>LastShownRecord: integer - Number of the last record displayed</li>
+ * <li>NumRecords: integer - Total number of records</li>
+ * <li>NumPages: integer - The number of pages</li>
+ * <li>CurrentPageNum (optional): integer - If OnlyOnePage is false, the number of the current page</li>
+ * <li>FirstPage (optional): GridField_FormAction - Button to go to the first page</li>
+ * <li>PreviousPage (optional): GridField_FormAction - Button to go to the previous page</li>
+ * <li>NextPage (optional): GridField_FormAction - Button to go to the next page</li>
+ * <li>LastPage (optional): GridField_FormAction - Button to go to last page</li>
+ * </ul>
*/
- public function getHTMLFragments($gridField) {
- if(!$this->checkDataType($gridField->getList())) return;
+ public function getTemplateParameters(GridField $gridField) {
+ if(!$this->checkDataType($gridField->getList())) return null;
- $state = $gridField->State->GridFieldPaginator;
- if(!is_int($state->currentPage))
- $state->currentPage = 1;
+ $state = $this->getGridPagerState($gridField);
// Figure out which page and record range we're on
$totalRows = $this->totalItems;
- if(!$totalRows) return array();
+ if(!$totalRows) return null;
$totalPages = (int)ceil($totalRows/$this->itemsPerPage);
if($totalPages == 0)
@@ -156,13 +178,14 @@ public function getHTMLFragments($gridField) {
// to sort out those first page, last page, pre and next pages, etc
// we are not render those in to the paginator.
if($totalPages === 1){
- $forTemplate = new ArrayData(array(
+ return new ArrayData(array(
'OnlyOnePage' => true,
'FirstShownRecord' => $firstShownRecord,
'LastShownRecord' => $lastShownRecord,
- 'NumRecords' => $totalRows
+ 'NumRecords' => $totalRows,
+ 'NumPages' => $totalPages
));
- }else{
+ } else {
// First page button
$firstPage = new GridField_FormAction($gridField, 'pagination_first', 'First', 'paginate', 1);
$firstPage->addExtraClass('ss-gridfield-firstpage');
@@ -191,9 +214,8 @@ public function getHTMLFragments($gridField) {
if($state->currentPage == $totalPages)
$lastPage = $lastPage->performDisabledTransformation();
-
// Render in template
- $forTemplate = new ArrayData(array(
+ return new ArrayData(array(
'OnlyOnePage' => false,
'FirstPage' => $firstPage,
'PreviousPage' => $previousPage,
@@ -206,11 +228,22 @@ public function getHTMLFragments($gridField) {
'NumRecords' => $totalRows
));
}
- return array(
- 'footer' => $forTemplate->renderWith('GridFieldPaginator_Row', array(
- 'Colspan'=>count($gridField->getColumns())
- )),
- );
+ }
+
+ /**
+ *
+ * @param GridField $gridField
+ * @return array
+ */
+ public function getHTMLFragments($gridField) {
+
+ $forTemplate = $this->getTemplateParameters($gridField);
+ if($forTemplate) {
+ return array(
+ 'footer' => $forTemplate->renderWith($this->itemClass,
+ array('Colspan'=>count($gridField->getColumns())))
+ );
+ }
}
/**
View
@@ -22,7 +22,7 @@
$experimental-support-for-svg: true;
-$gf_colour_gradient_dark: darken($color-base, 8%);
+$gf_colour_gradient_dark: darken($color-base, 8%);
$gf_colour_header_border: $gf_colour_gradient_dark;
$gf_colour_subheader: saturate(lighten($color-base, 15%),5%);
$gf_colour_border: rgba(0,0,0,.1);
@@ -76,6 +76,15 @@ $gf_grid_x: 16px;
margin-left:5px;
font-size: $gf_grid_y*1.2;
}
+
+ .pagination-records-number
+ {
+ font-size: 1.0em;
+ padding: 6px 3px 6px 0;
+ color: $color-text-light;
+ @include single-text-shadow($gf_colour_text_shadow, 0px, -1px, 0);
+ font-weight: normal;
+ }
}
.left {
float:left;
@@ -327,7 +336,7 @@ $gf_grid_x: 16px;
padding: 5px;
border-right: 1px solid $gf_colour_border;
- div {
+ div {
&.fieldgroup,&.fieldgroup-field {
width: 100%;
position:relative;
@@ -338,7 +347,6 @@ $gf_grid_x: 16px;
&.filter-buttons{
min-width:0;
div{
- @extend .col-buttons;
width:auto;
display:inline;
}
@@ -0,0 +1,6 @@
+<span class="pagination-records-number">
+ <% _t('Pagination.View', 'View', 'Verb. Example: View 1 of 2') %>
+ {$FirstShownRecord}&ndash;{$LastShownRecord}
+ <% _t('TableListField_PageControls.ss.OF', 'of', 'Example: View 1 of 2') %>
+ $NumRecords
+</span>
@@ -15,7 +15,7 @@
<% end_if %>
<span class="pagination-records-number">
<% _t('Pagination.View', 'View', 'Verb. Example: View 1 of 2') %>
- $FirstShownRecord - $LastShownRecord
+ {$FirstShownRecord}&ndash;{$LastShownRecord}
<% _t('TableListField_PageControls.ss.OF', 'of', 'Example: View 1 of 2') %>
$NumRecords
</span>
@@ -33,6 +33,7 @@ public function testGridFieldDefaultConfig() {
$sort = new GridFieldSortableHeader(),
$filter = new GridFieldFilterHeader(),
new GridFieldDataColumns(),
+ new GridFieldPageCount('toolbar-header-right'),
$pagination = new GridFieldPaginator(),
new GridState_Component(),
));
@@ -18,7 +18,11 @@ class GridFieldPaginatorTest extends FunctionalTest {
public function setUp() {
parent::setUp();
$this->list = new DataList('GridFieldTest_Team');
- $config = GridFieldConfig::create()->addComponent(new GridFieldPaginator(2));
+ $config = GridFieldConfig::create()->addComponents(
+ new GridFieldToolbarHeader(), // Required to support pagecount
+ new GridFieldPaginator(2),
+ new GridFieldPageCount('toolbar-header-right')
+ );
$this->gridField = new GridField('testfield', 'testfield', $this->list, $config);
$this->form = new Form(new Controller(), 'mockform', new FieldList(array($this->gridField)), new FieldList());
}
@@ -28,6 +32,9 @@ public function testThereIsPaginatorWhenMoreThanOnePage() {
$content = new CSSContentParser($fieldHolder);
// Check that there is paginator render into the footer
$this->assertEquals(1, count($content->getBySelector('.datagrid-pagination')));
+
+ // Check that the header and footer both contains a page count
+ $this->assertEquals(2, count($content->getBySelector('.pagination-records-number')));
}
public function testThereIsNoPaginatorWhenOnlyOnePage() {
@@ -42,6 +49,6 @@ public function testThereIsNoPaginatorWhenOnlyOnePage() {
$this->assertEquals(0, count($content->getBySelector('.datagrid-pagination')));
// Check that there is still 'View 1 - 4 of 4' part on the left of the paginator
- $this->assertEquals(1, count($content->getBySelector('.pagination-records-number')));
+ $this->assertEquals(2, count($content->getBySelector('.pagination-records-number')));
}
}

0 comments on commit f265595

Please sign in to comment.