mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT Renamed DataGrid to GridField
This commit is contained in:
parent
a2c7175caa
commit
b229c17e1d
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
.sass-cache
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
|
@ -1,17 +0,0 @@
|
||||
/** Core styles for the basic DataGrid form field without any specific style. @package sapphire @subpackage scss */
|
||||
.ss-datagrid { border: none; }
|
||||
.ss-datagrid table { width: 100%; border-collapse: collapse; border-spacing: 0; background: #fff; border: 1px solid #c1c1c1; }
|
||||
.ss-datagrid thead { color: #5a5a5a; background: #dadada; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f3f3f3), color-stop(100%, #dadada)); background-image: -webkit-linear-gradient(#f3f3f3, #dadada); background-image: -moz-linear-gradient(#f3f3f3, #dadada); background-image: -o-linear-gradient(#f3f3f3, #dadada); background-image: -ms-linear-gradient(#f3f3f3, #dadada); background-image: linear-gradient(#f3f3f3, #dadada); }
|
||||
.ss-datagrid thead th { font-weight: bold; padding: 8px 24px 8px 8px; position: relative; border: 1px solid #c1c1c1; border-width: 0 1px 1px 0; }
|
||||
.ss-datagrid thead th.ss-datagrid-sortable.hover { color: #747474; cursor: pointer; background: #f3f3f3; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, #e7e7e7)); background-image: -webkit-linear-gradient(#ffffff, #e7e7e7); background-image: -moz-linear-gradient(#ffffff, #e7e7e7); background-image: -o-linear-gradient(#ffffff, #e7e7e7); background-image: -ms-linear-gradient(#ffffff, #e7e7e7); background-image: linear-gradient(#ffffff, #e7e7e7); }
|
||||
.ss-datagrid thead th.ss-datagrid-sorted { background: #e7e7e7; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #dadada), color-stop(100%, #f3f3f3)); background-image: -webkit-linear-gradient(#dadada, #f3f3f3); background-image: -moz-linear-gradient(#dadada, #f3f3f3); background-image: -o-linear-gradient(#dadada, #f3f3f3); background-image: -ms-linear-gradient(#dadada, #f3f3f3); background-image: linear-gradient(#dadada, #f3f3f3); }
|
||||
.ss-datagrid thead th.ss-datagrid-sorted.hover { background: #f3f3f3; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #e7e7e7), color-stop(100%, #ffffff)); background-image: -webkit-linear-gradient(#e7e7e7, #ffffff); background-image: -moz-linear-gradient(#e7e7e7, #ffffff); background-image: -o-linear-gradient(#e7e7e7, #ffffff); background-image: -ms-linear-gradient(#e7e7e7, #ffffff); background-image: linear-gradient(#e7e7e7, #ffffff); }
|
||||
.ss-datagrid thead th .ui-icon { position: absolute; top: 5px; right: 0; }
|
||||
.ss-datagrid thead th.ss-datagrid-desc .ui-icon { background-position: 0 -48px; }
|
||||
.ss-datagrid thead th.ss-datagrid-asc .ui-icon { background-position: -64px -48px; }
|
||||
.ss-datagrid td { padding: 8px; border-right: 1px solid #f3f3f3; }
|
||||
.ss-datagrid td.ss-datagrid-last { border-right: none; }
|
||||
.ss-datagrid tr.ss-datagrid-even { border: 1px solid #c6e5f6; border-width: 1px 0; background: #f2f9fd; }
|
||||
.ss-datagrid tr.ss-datagrid-even.ss-datagrid-last { border-bottom: none; }
|
||||
.ss-datagrid tr.ss-datagrid-even td { border-right: 1px solid #dceffa; }
|
||||
.ss-datagrid tr.ss-datagrid-even td.ss-datagrid-last { border-right: none; }
|
17
css/GridField.css
Normal file
17
css/GridField.css
Normal file
@ -0,0 +1,17 @@
|
||||
/** Core styles for the basic GridField form field without any specific style. @package sapphire @subpackage scss */
|
||||
.ss-gridfield { border: none; }
|
||||
.ss-gridfield table { width: 100%; border-collapse: collapse; border-spacing: 0; background: #fff; border: 1px solid #c1c1c1; }
|
||||
.ss-gridfield thead { color: #5a5a5a; background: #dadada; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f3f3f3), color-stop(100%, #dadada)); background-image: -webkit-linear-gradient(#f3f3f3, #dadada); background-image: -moz-linear-gradient(#f3f3f3, #dadada); background-image: -o-linear-gradient(#f3f3f3, #dadada); background-image: -ms-linear-gradient(#f3f3f3, #dadada); background-image: linear-gradient(#f3f3f3, #dadada); }
|
||||
.ss-gridfield thead th { font-weight: bold; padding: 8px 24px 8px 8px; position: relative; border: 1px solid #c1c1c1; border-width: 0 1px 1px 0; }
|
||||
.ss-gridfield thead th.ss-gridfield-sortable.hover { color: #747474; cursor: pointer; background: #f3f3f3; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff), color-stop(100%, #e7e7e7)); background-image: -webkit-linear-gradient(#ffffff, #e7e7e7); background-image: -moz-linear-gradient(#ffffff, #e7e7e7); background-image: -o-linear-gradient(#ffffff, #e7e7e7); background-image: -ms-linear-gradient(#ffffff, #e7e7e7); background-image: linear-gradient(#ffffff, #e7e7e7); }
|
||||
.ss-gridfield thead th.ss-gridfield-sorted { background: #e7e7e7; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #dadada), color-stop(100%, #f3f3f3)); background-image: -webkit-linear-gradient(#dadada, #f3f3f3); background-image: -moz-linear-gradient(#dadada, #f3f3f3); background-image: -o-linear-gradient(#dadada, #f3f3f3); background-image: -ms-linear-gradient(#dadada, #f3f3f3); background-image: linear-gradient(#dadada, #f3f3f3); }
|
||||
.ss-gridfield thead th.ss-gridfield-sorted.hover { background: #f3f3f3; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #e7e7e7), color-stop(100%, #f9f9f9)); background-image: -webkit-linear-gradient(#e7e7e7, #f9f9f9); background-image: -moz-linear-gradient(#e7e7e7, #f9f9f9); background-image: -o-linear-gradient(#e7e7e7, #f9f9f9); background-image: -ms-linear-gradient(#e7e7e7, #f9f9f9); background-image: linear-gradient(#e7e7e7, #f9f9f9); }
|
||||
.ss-gridfield thead th .ui-icon { position: absolute; top: 5px; right: 0; }
|
||||
.ss-gridfield thead th.ss-gridfield-desc .ui-icon { background-position: 0 -48px; }
|
||||
.ss-gridfield thead th.ss-gridfield-asc .ui-icon { background-position: -64px -48px; }
|
||||
.ss-gridfield td { padding: 8px; border-right: 1px solid #f3f3f3; }
|
||||
.ss-gridfield td.ss-gridfield-last { border-right: none; }
|
||||
.ss-gridfield tr.ss-gridfield-even { border: 1px solid #c6e5f6; border-width: 1px 0; background: #f2f9fd; }
|
||||
.ss-gridfield tr.ss-gridfield-even.ss-gridfield-last { border-bottom: none; }
|
||||
.ss-gridfield tr.ss-gridfield-even td { border-right: 1px solid #dceffa; }
|
||||
.ss-gridfield tr.ss-gridfield-even td.ss-gridfield-last { border-right: none; }
|
@ -1,129 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Datagrid
|
||||
*
|
||||
* This field takes care of displaying a table of a list of data
|
||||
*
|
||||
*/
|
||||
class Datagrid extends FormField {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var SS_list
|
||||
*/
|
||||
protected $datasource = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $dataPresenterClassName = "DatagridPresenter";
|
||||
|
||||
/**
|
||||
*
|
||||
* @var DatagridPresenter
|
||||
*/
|
||||
protected $datagridPresenter = null;
|
||||
|
||||
/**
|
||||
* @var string - the name of the DataObject that the Datagrid will display
|
||||
*/
|
||||
protected $modelClassName = '';
|
||||
|
||||
/**
|
||||
* Creates a new datagrid field
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $title
|
||||
* @param SS_list $datasource
|
||||
* @param Form $form
|
||||
* @param string $dataPresenterClassName
|
||||
*/
|
||||
function __construct($name, $title = null, SS_list $datasource = null, Form $form = null, $dataPresenterClassName = null) {
|
||||
parent::__construct($name, $title, null, $form);
|
||||
if ($datasource) $this->setDatasource($datasource);
|
||||
if ($dataPresenterClassName) $this->setDataPresenter($dataPresenterClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $modelClassName
|
||||
*/
|
||||
function setModelClass($modelClassName) {
|
||||
$this->modelClassName = $modelClassName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $dataPresenterClassName
|
||||
* @throws Exception
|
||||
*/
|
||||
function setDataPresenter($dataPresenterClassName) {
|
||||
if(!$dataPresenterClassName){
|
||||
throw new Exception('Datapresenter for Datagrid must be set with a class');
|
||||
}
|
||||
if(!class_exists($dataPresenterClassName)){
|
||||
throw new Exception('Datapresenter for Datagrid must be set with an existing class');
|
||||
}
|
||||
|
||||
if($dataPresenterClassName !='DatagridPresenter' && !ClassInfo::is_subclass_of($dataPresenterClassName, 'DatagridPresenter')){
|
||||
throw new Exception('Datapresenter "$dataPresenterClassName" must inherit DatagridPresenter' );
|
||||
}
|
||||
$this->dataPresenterClassName = $dataPresenterClassName;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return type
|
||||
*/
|
||||
function getModelClass() {
|
||||
if ($this->modelClassName) {
|
||||
return $this->modelClassName;
|
||||
}
|
||||
if ($this->datasource->dataClass) {
|
||||
return $this->datasource->dataClass;
|
||||
}
|
||||
throw new Exception(get_class($this).' does not have a modelClassName');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the datasource
|
||||
*
|
||||
* @param SS_List $datasource
|
||||
*/
|
||||
public function setDatasource(SS_List $datasource) {
|
||||
$this->datasource = $datasource;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the datasource
|
||||
*
|
||||
* @return SS_list
|
||||
*/
|
||||
public function getDatasource() {
|
||||
return $this->datasource;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return DatagridPresenter
|
||||
*/
|
||||
public function getDatagridPresenter(){
|
||||
if(!$this->datagridPresenter) {
|
||||
$this->datagridPresenter = new $this->dataPresenterClassName();
|
||||
$this->datagridPresenter->setDatagrid($this);
|
||||
}
|
||||
return $this->datagridPresenter;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string - html for the form
|
||||
*/
|
||||
function FieldHolder() {
|
||||
return $this->getDatagridPresenter()->render();
|
||||
}
|
||||
}
|
140
forms/GridField.php
Normal file
140
forms/GridField.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* Displays a {@link SS_List} in a grid format.
|
||||
*
|
||||
* @package sapphire
|
||||
* @subpackage forms
|
||||
*/
|
||||
class GridField extends FormField {
|
||||
|
||||
/**
|
||||
* @var SS_List
|
||||
*/
|
||||
protected $dataSource = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $presenterClassName = "GridFieldPresenter";
|
||||
|
||||
/**
|
||||
* @var GridFieldPresenter
|
||||
*/
|
||||
protected $presenter = null;
|
||||
|
||||
/**
|
||||
* @var string - the classname of the DataObject that the GridField will display
|
||||
*/
|
||||
protected $modelClassName = '';
|
||||
|
||||
/**
|
||||
* Creates a new GridField field
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $title
|
||||
* @param SS_List $datasource
|
||||
* @param Form $form
|
||||
* @param string $dataPresenterClassName
|
||||
*/
|
||||
public function __construct($name, $title = null, SS_List $datasource = null, Form $form = null, $dataPresenterClassName = 'GridFieldPresenter') {
|
||||
parent::__construct($name, $title, null, $form);
|
||||
|
||||
if ($datasource) {
|
||||
$this->setDatasource($datasource);
|
||||
}
|
||||
|
||||
$this->setPresenter($dataPresenterClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $modelClassName
|
||||
*/
|
||||
public function setModelClass($modelClassName) {
|
||||
$this->modelClassName = $modelClassName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
public function getModelClass() {
|
||||
if ($this->modelClassName) {
|
||||
return $this->modelClassName;
|
||||
}
|
||||
if ($this->datasource->dataClass) {
|
||||
return $this->datasource->dataClass;
|
||||
}
|
||||
|
||||
throw new Exception(get_class($this).' does not have a modelClassName');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|GridFieldPresenter
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function setPresenter($presenter) {
|
||||
if(!$presenter){
|
||||
throw new Exception('setPresenter() for GridField must be set with a class');
|
||||
}
|
||||
|
||||
if(is_object($presenter)) {
|
||||
$this->presenter = $presenter;
|
||||
$this->presenter->setGridField($this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!class_exists($presenter)){
|
||||
throw new Exception('DataPresenter for GridField must be set with an existing class, '.$presenter.' does not exists.');
|
||||
}
|
||||
|
||||
if($presenter !='GridFieldPresenter' && !ClassInfo::is_subclass_of($presenter, 'GridFieldPresenter')) {
|
||||
throw new Exception(sprintf(
|
||||
'DataPresenter "%s" must subclass GridFieldPresenter', $presenter
|
||||
));
|
||||
}
|
||||
|
||||
$this->presenter = new $presenter;
|
||||
$this->presenter->setGridField($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return GridFieldPresenter
|
||||
*/
|
||||
public function getPresenter(){
|
||||
return $this->presenter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the datasource
|
||||
*
|
||||
* @param SS_List $datasource
|
||||
*/
|
||||
public function setDataSource(SS_List $datasource) {
|
||||
$this->datasource = $datasource;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the datasource
|
||||
*
|
||||
* @return SS_List
|
||||
*/
|
||||
public function getDataSource() {
|
||||
return $this->datasource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string - html for the form
|
||||
*/
|
||||
function FieldHolder() {
|
||||
return $this->getPresenter()->render();
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Description of DatagridPresenter
|
||||
*
|
||||
* @see GridField
|
||||
* @package sapphire
|
||||
*/
|
||||
class DatagridPresenter extends ViewableData {
|
||||
class GridFieldPresenter extends ViewableData {
|
||||
|
||||
/**
|
||||
* Template override
|
||||
*
|
||||
* @var string $template
|
||||
*/
|
||||
protected $template = 'DatagridPresenter';
|
||||
protected $template = 'GridFieldPresenter';
|
||||
|
||||
/**
|
||||
* Class name for each item/row
|
||||
*
|
||||
* @var string $itemClass
|
||||
*/
|
||||
protected $itemClass = 'DatagridPresenter_Item';
|
||||
protected $itemClass = 'GridFieldPresenter_Item';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Datagrid
|
||||
* @var GridField
|
||||
*/
|
||||
protected $datagrid = null;
|
||||
protected $GridField = null;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $fieldCasting = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $fieldFormatting = array();
|
||||
|
||||
/**
|
||||
* List of columns and direction that the {@link GridFieldPresenter} is
|
||||
* sorted in.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $sorting = array();
|
||||
|
||||
/**
|
||||
* @param string $template
|
||||
*/
|
||||
function setTemplate($template){
|
||||
@ -47,82 +51,122 @@ class DatagridPresenter extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Datagrid $datagrid
|
||||
* @param GridField $GridField
|
||||
*/
|
||||
public function setDatagrid(Datagrid $datagrid){
|
||||
$this->datagrid = $datagrid;
|
||||
public function setGridField(GridField $grid){
|
||||
$this->GridField = $grid;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Datagrid
|
||||
* @return GridField
|
||||
*/
|
||||
public function getDatagrid(){
|
||||
return $this->datagrid;
|
||||
public function getGridField(){
|
||||
return $this->GridField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a ArrayList of Datagrid_Item objects, suitable for display in the template.
|
||||
* Sort the grid by columns
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $direction
|
||||
*/
|
||||
public function sort($column, $direction = 'asc') {
|
||||
$this->sorting[$column] = $direction;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an {@link ArrayList} of {@link GridField_Item} objects, suitable for display in the template.
|
||||
*
|
||||
* @return ArrayList
|
||||
*/
|
||||
public function Items() {
|
||||
$fieldItems = new ArrayList();
|
||||
if($items = $this->getDatagrid()->getDatasource()) {
|
||||
$items = new ArrayList();
|
||||
|
||||
if($this->sorting) {
|
||||
$this->setSorting($this->sorting);
|
||||
}
|
||||
|
||||
if($sources = $this->getGridField()->getDataSource()) {
|
||||
$counter = 0;
|
||||
foreach($items as $item) {
|
||||
if(!$item) {
|
||||
|
||||
foreach($sources as $source) {
|
||||
if(!$source) {
|
||||
continue;
|
||||
}
|
||||
$datagridPresenterItem = new $this->itemClass($item, $this);
|
||||
$datagridPresenterItem->iteratorProperties($counter++, $items->count());
|
||||
$fieldItems->push($datagridPresenterItem);
|
||||
|
||||
$itemPresenter = new $this->itemClass($source, $this);
|
||||
$itemPresenter->iteratorProperties($counter++, $sources->count());
|
||||
|
||||
$items->push($itemPresenter);
|
||||
}
|
||||
}
|
||||
return $fieldItems;
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the headers or column names for this grid
|
||||
*
|
||||
* The returning array will have the format of
|
||||
* array(
|
||||
* 'FirstName' => 'First name',
|
||||
* 'Description' => 'A nice description'
|
||||
* )
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'FirstName' => 'First name',
|
||||
* 'Description' => 'A nice description'
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @return ArrayList
|
||||
* @throws Exception
|
||||
*/
|
||||
public function Headers() {
|
||||
|
||||
if(!$this->getDatasource()) {
|
||||
throw new Exception(get_class($this->getDatagrid()). ' needs an data source to be able to render the form');
|
||||
throw new Exception(sprintf(
|
||||
'%s needs an data source to be able to render the form', get_class($this->getGridField())
|
||||
));
|
||||
}
|
||||
|
||||
$summaryFields = singleton($this->getModelClass())->summaryFields();
|
||||
|
||||
return $this->summaryFieldsToList($summaryFields);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return SS_List
|
||||
*/
|
||||
protected function getDataSource() {
|
||||
return $this->getDatagrid()->getDatasource();
|
||||
return $this->getGridField()->getDatasource();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string - name of model
|
||||
*/
|
||||
protected function getModelClass() {
|
||||
return $this->getDatagrid()->getModelClass();
|
||||
return $this->getGridField()->getModelClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the combined sorting on the datasource
|
||||
*
|
||||
* If the sorting isn't set in one go on the datasource, only the latest sort
|
||||
* will be executed.s
|
||||
*
|
||||
* @param array $sortColumns
|
||||
*/
|
||||
protected function setSorting(array $sortColumns) {
|
||||
$resultColumns = array();
|
||||
|
||||
foreach($sortColumns as $column => $sortOrder) {
|
||||
$resultColumns[] = sprintf("%s %s", $column ,$sortOrder);
|
||||
}
|
||||
|
||||
$sort = implode(', ', $resultColumns);
|
||||
$this->getDataSource()->sort($sort);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function FieldList() {
|
||||
@ -134,30 +178,41 @@ class DatagridPresenter extends ViewableData {
|
||||
* by the Form renderer
|
||||
*
|
||||
* @param array $summaryFields
|
||||
*
|
||||
* @return ArrayList
|
||||
*/
|
||||
protected function summaryFieldsToList($summaryFields) {
|
||||
$fieldHeaders = new ArrayList();
|
||||
if (is_array($summaryFields)){
|
||||
$headers = new ArrayList();
|
||||
|
||||
if(is_array($summaryFields)) {
|
||||
$counter = 0;
|
||||
foreach ($summaryFields as $name=>$title){
|
||||
$arrayData = new ArrayData(array(
|
||||
'Name'=>$name,
|
||||
'Title'=>$title,
|
||||
'IsSortable'=>true,
|
||||
'IsSorted'=>false,
|
||||
'SortedDirection'=>'desc')
|
||||
|
||||
foreach ($summaryFields as $name => $title) {
|
||||
$data = array(
|
||||
'Name' => $name,
|
||||
'Title' => $title,
|
||||
'IsSortable' => true,
|
||||
'IsSorted' => false,
|
||||
'SortedDirection' => 'asc'
|
||||
);
|
||||
$arrayData->iteratorProperties($counter++, count($summaryFields));
|
||||
$fieldHeaders->push($arrayData);
|
||||
|
||||
if(array_key_exists($name, $this->sorting)) {
|
||||
$data['IsSorted'] = true;
|
||||
$data['SortedDirection'] = $this->sorting[$name];
|
||||
}
|
||||
|
||||
$result = new ArrayData($data);
|
||||
$result->iteratorProperties($counter++, count($summaryFields));
|
||||
|
||||
$headers->push($result);
|
||||
}
|
||||
}
|
||||
return $fieldHeaders;
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $casting
|
||||
* @param array $casting
|
||||
*/
|
||||
function setFieldCasting($casting) {
|
||||
$this->fieldCasting = $casting;
|
||||
@ -172,7 +227,6 @@ class DatagridPresenter extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string - html
|
||||
*/
|
||||
function render(){
|
||||
@ -181,36 +235,36 @@ class DatagridPresenter extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
* A single record in a Datagrid.
|
||||
* @package forms
|
||||
* @see Datagrid
|
||||
* A single record in a GridField.
|
||||
*
|
||||
* @package sapphire
|
||||
* @see GridField
|
||||
*/
|
||||
class DatagridPresenter_Item extends ViewableData {
|
||||
class GridFieldPresenter_Item extends ViewableData {
|
||||
|
||||
/**
|
||||
* @var DataObject The underlying data record,
|
||||
* usually an element of {@link Datagrid->datasource()}.
|
||||
* @var Object The underlying record, usually an element of
|
||||
* {@link GridField->datasource()}.
|
||||
*/
|
||||
protected $item;
|
||||
|
||||
/**
|
||||
* @var DatagridPresenter
|
||||
* @var GridFieldPresenter
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param type $item
|
||||
* @param type $parent
|
||||
* @param Object $item
|
||||
* @param GridFieldPresenter $parent
|
||||
*/
|
||||
public function __construct($item, $parent) {
|
||||
$this->failover = $this->item = $item;
|
||||
$this->parent = $parent;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function ID() {
|
||||
@ -218,7 +272,6 @@ class DatagridPresenter_Item extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return type
|
||||
*/
|
||||
public function Parent() {
|
||||
@ -227,14 +280,14 @@ class DatagridPresenter_Item extends ViewableData {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bool $xmlSafe
|
||||
*
|
||||
* @return ArrayList
|
||||
*/
|
||||
public function Fields($xmlSafe = true) {
|
||||
$list = $this->parent->FieldList();
|
||||
|
||||
$counter = 0;
|
||||
|
||||
foreach($list as $fieldName => $fieldTitle) {
|
||||
$value = "";
|
||||
|
||||
@ -242,10 +295,12 @@ class DatagridPresenter_Item extends ViewableData {
|
||||
// This supports simple FieldName syntax
|
||||
if(strpos($fieldName,'.') === false) {
|
||||
$value = ($this->item->XML_val($fieldName) && $xmlSafe) ? $this->item->XML_val($fieldName) : $this->item->RAW_val($fieldName);
|
||||
|
||||
// This support the syntax fieldName = Relation.RelatedField
|
||||
} else {
|
||||
$fieldNameParts = explode('.', $fieldName) ;
|
||||
$tmpItem = $this->item;
|
||||
|
||||
for($j=0;$j<sizeof($fieldNameParts);$j++) {
|
||||
$relationMethod = $fieldNameParts[$j];
|
||||
$idField = $relationMethod . 'ID';
|
||||
@ -274,7 +329,7 @@ class DatagridPresenter_Item extends ViewableData {
|
||||
}
|
||||
|
||||
//escape
|
||||
if($escape = $this->parent->getDatagrid()->fieldEscape){
|
||||
if($escape = $this->parent->getGridField()->fieldEscape){
|
||||
foreach($escape as $search => $replace){
|
||||
$value = str_replace($search, $replace, $value);
|
||||
}
|
||||
@ -288,6 +343,7 @@ class DatagridPresenter_Item extends ViewableData {
|
||||
$arrayData->iteratorProperties($counter++, count($list));
|
||||
$fields[] = $arrayData;
|
||||
}
|
||||
|
||||
return new ArrayList($fields);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Core styles for the basic DataGrid form field without any specific style.
|
||||
* Core styles for the basic GridField form field without any specific style.
|
||||
*
|
||||
* @package sapphire
|
||||
* @subpackage scss
|
||||
@ -10,7 +10,7 @@
|
||||
$base: #dadada;
|
||||
$zebra: #f2f9fd;
|
||||
|
||||
.ss-datagrid {
|
||||
.ss-gridfield {
|
||||
border: none;
|
||||
|
||||
table {
|
||||
@ -38,7 +38,7 @@ $zebra: #f2f9fd;
|
||||
border: 1px solid darken($base, 10%);
|
||||
border-width: 0 1px 1px 0;
|
||||
|
||||
&.ss-datagrid-sortable {
|
||||
&.ss-gridfield-sortable {
|
||||
|
||||
&.hover {
|
||||
color: darken($base, 40%);
|
||||
@ -52,7 +52,7 @@ $zebra: #f2f9fd;
|
||||
}
|
||||
}
|
||||
|
||||
&.ss-datagrid-sorted {
|
||||
&.ss-gridfield-sorted {
|
||||
background: lighten($base, 5%);
|
||||
|
||||
@include background-image(linear-gradient(
|
||||
@ -74,11 +74,11 @@ $zebra: #f2f9fd;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&.ss-datagrid-desc .ui-icon {
|
||||
&.ss-gridfield-desc .ui-icon {
|
||||
background-position: 0 -48px;
|
||||
}
|
||||
|
||||
&.ss-datagrid-asc .ui-icon {
|
||||
&.ss-gridfield-asc .ui-icon {
|
||||
background-position: -64px -48px;
|
||||
}
|
||||
}
|
||||
@ -92,26 +92,26 @@ $zebra: #f2f9fd;
|
||||
padding: 8px;
|
||||
border-right: 1px solid lighten($base, 10%);
|
||||
|
||||
&.ss-datagrid-last {
|
||||
&.ss-gridfield-last {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
|
||||
&.ss-datagrid-even {
|
||||
&.ss-gridfield-even {
|
||||
border: 1px solid darken($zebra, 10%);
|
||||
border-width: 1px 0;
|
||||
background: $zebra;
|
||||
|
||||
&.ss-datagrid-last {
|
||||
&.ss-gridfield-last {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
td {
|
||||
border-right: 1px solid darken($zebra, 5%);
|
||||
|
||||
&.ss-datagrid-last {
|
||||
&.ss-gridfield-last {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
25
templates/GridField.ss
Normal file
25
templates/GridField.ss
Normal file
@ -0,0 +1,25 @@
|
||||
<% require css(sapphire/thirdparty/jquery-ui-themes/smoothness/jquery-ui.css) %>
|
||||
<% require css(sapphire/css/GridField.css) %>
|
||||
|
||||
<div class="ss-gridfield ui-state-default">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<% control Headings %>
|
||||
<th class="<% if FirstLast %>ss-gridfield-{$FirstLast} <% if IsSortable %> ss-gridfield-sortable<% end_if %> <% if IsSorted %>ss-gridfield-sorted ss-gridfield-{$SortedDirection}">
|
||||
$Title <span class="ui-icon"></span></th>
|
||||
<% end_control %>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<% control Items %>
|
||||
<% include GridField_Item %>
|
||||
<% end_control %>
|
||||
</tbody>
|
||||
|
||||
<tfoot>
|
||||
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
@ -1,12 +1,12 @@
|
||||
<% require css(sapphire/thirdparty/jquery-ui-themes/smoothness/jquery-ui.css) %>
|
||||
<% require css(sapphire/css/DataGrid.css) %>
|
||||
<% require css(sapphire/css/GridField.css) %>
|
||||
|
||||
<div class="ss-datagrid ui-state-default">
|
||||
<div class="ss-gridfield ui-state-default">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<% control Headers %>
|
||||
<th class="<% if FirstLast %>ss-datagrid-{$FirstLast}<% end_if %><% if IsSortable %> ss-datagrid-sortable<% end_if %><% if IsSorted %> ss-datagrid-sorted ss-datagrid-{$SortedDirection}<% end_if %>">
|
||||
<th class="<% if FirstLast %>ss-gridfield-{$FirstLast}<% end_if %><% if IsSortable %> ss-gridfield-sortable<% end_if %><% if IsSorted %> ss-gridfield-sorted ss-gridfield-{$SortedDirection}<% end_if %>">
|
||||
$Title <span class="ui-icon"></span></th>
|
||||
<% end_control %>
|
||||
</tr>
|
||||
@ -14,7 +14,7 @@
|
||||
|
||||
<tbody>
|
||||
<% control Items %>
|
||||
<% include DataGrid_Item %>
|
||||
<% include GridField_Item %>
|
||||
<% end_control %>
|
||||
</tbody>
|
||||
|
@ -1,5 +0,0 @@
|
||||
<tr class="ss-datagrid-{$EvenOdd}">
|
||||
<% control Fields %>
|
||||
<td <% if FirstLast %>class="ss-datagrid-{$FirstLast}"<% end_if %>>$Value</td>
|
||||
<% end_control %>
|
||||
</tr>
|
5
templates/Includes/GridField_Item.ss
Normal file
5
templates/Includes/GridField_Item.ss
Normal file
@ -0,0 +1,5 @@
|
||||
<tr class="ss-gridfield-{$EvenOdd}">
|
||||
<% control Fields %>
|
||||
<td <% if FirstLast %>class="ss-gridfield-{$FirstLast}"<% end_if %>>$Value</td>
|
||||
<% end_control %>
|
||||
</tr>
|
@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is a functional test for DatagridFunctionalTest
|
||||
*
|
||||
*/
|
||||
class DatagridFunctionalTest extends FunctionalTest {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
static $fixture_file = 'sapphire/tests/forms/DatagridTest.yml';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extraDataObjects = array(
|
||||
'DatagridTest_Person',
|
||||
);
|
||||
|
||||
public function testAddToForm() {
|
||||
$firstPerson = $this->objFromFixture('DatagridTest_Person', 'first');
|
||||
$response = $this->get("DatagridFunctionalTest_Controller/");
|
||||
$this->assertContains($firstPerson->Name, $response->getBody());
|
||||
}
|
||||
}
|
||||
|
||||
class DatagridFunctionalTest_Controller extends Controller {
|
||||
|
||||
protected $template = 'BlankPage';
|
||||
|
||||
function Link($action = null) {
|
||||
return Controller::join_links('DatagridFunctionalTest_Controller', $action);
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$grid = new Datagrid('testgrid');
|
||||
$dataSource = DataList::create("DatagridTest_Person")->sort("Name");
|
||||
$grid->setDataSource($dataSource);
|
||||
$form = new Form($this, 'gridform', new FieldList($grid), new FieldList(new FormAction('rerender', 'rerender')));
|
||||
return array('Form'=>$form);
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is a Unittest class for DatagridPresenterTest
|
||||
*
|
||||
*/
|
||||
class DatagridPresenterTest extends SapphireTest {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
static $fixture_file = 'sapphire/tests/forms/DatagridTest.yml';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extraDataObjects = array(
|
||||
'DatagridTest_Person',
|
||||
);
|
||||
|
||||
public function testGetInstance() {
|
||||
$this->assertTrue(new DatagridPresenter instanceof DatagridPresenter, 'Trying to find an instance of DatagridPresenter');
|
||||
}
|
||||
|
||||
public function testHeaders() {
|
||||
$presenter = new DatagridPresenter();
|
||||
$grid = new Datagrid('testgrid', 'testgrid', new DataList('DatagridTest_Person'));
|
||||
$presenter->setDatagrid($grid);
|
||||
$headers = $presenter->Headers()->first();
|
||||
|
||||
$this->assertEquals(1, count($headers));
|
||||
$this->assertEquals('Name', $headers->Name );
|
||||
}
|
||||
|
||||
public function testItemsReturnCorrectNumberOfItems() {
|
||||
$presenter = new DatagridPresenter();
|
||||
$grid = new Datagrid('testgrid', 'testgrid', new DataList('DatagridTest_Person'));
|
||||
$presenter->setDatagrid($grid);
|
||||
$this->assertEquals(2, $presenter->Items()->count());
|
||||
}
|
||||
|
||||
}
|
45
tests/forms/GridFieldFunctionalTest.php
Normal file
45
tests/forms/GridFieldFunctionalTest.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is a functional test for GridFieldFunctionalTest
|
||||
*
|
||||
*/
|
||||
class GridFieldFunctionalTest extends FunctionalTest {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
static $fixture_file = 'sapphire/tests/forms/GridFieldTest.yml';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extraDataObjects = array(
|
||||
'GridFieldTest_Person',
|
||||
);
|
||||
|
||||
public function testAddToForm() {
|
||||
$firstPerson = $this->objFromFixture('GridFieldTest_Person', 'first');
|
||||
$response = $this->get("GridFieldFunctionalTest_Controller/");
|
||||
$this->assertContains($firstPerson->Name, $response->getBody());
|
||||
}
|
||||
}
|
||||
|
||||
class GridFieldFunctionalTest_Controller extends Controller {
|
||||
|
||||
protected $template = 'BlankPage';
|
||||
|
||||
function Link($action = null) {
|
||||
return Controller::join_links('GridFieldFunctionalTest_Controller', $action);
|
||||
}
|
||||
|
||||
public function index() {
|
||||
$grid = new GridField('testgrid');
|
||||
$dataSource = DataList::create("GridFieldTest_Person")->sort("Name");
|
||||
$grid->setDataSource($dataSource);
|
||||
$form = new Form($this, 'gridform', new FieldList($grid), new FieldList(new FormAction('rerender', 'rerender')));
|
||||
return array('Form'=>$form);
|
||||
}
|
||||
}
|
55
tests/forms/GridFieldPresenterTest.php
Normal file
55
tests/forms/GridFieldPresenterTest.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package sapphire
|
||||
* @subpackage tests
|
||||
*/
|
||||
class GridFieldPresenterTest extends SapphireTest {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
static $fixture_file = 'sapphire/tests/forms/GridFieldTest.yml';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extraDataObjects = array(
|
||||
'GridFieldTest_Person',
|
||||
);
|
||||
|
||||
public function testGetInstance() {
|
||||
$this->assertTrue(new GridFieldPresenter instanceof GridFieldPresenter, 'Trying to find an instance of GridFieldPresenter');
|
||||
}
|
||||
|
||||
public function testHeaders() {
|
||||
$presenter = new GridFieldPresenter();
|
||||
$grid = new GridField('testgrid', 'testgrid', new DataList('GridFieldTest_Person'));
|
||||
$presenter->setGridField($grid);
|
||||
$headers = $presenter->Headers()->first();
|
||||
|
||||
$this->assertEquals(1, count($headers));
|
||||
$this->assertEquals('Name', $headers->Name );
|
||||
}
|
||||
|
||||
public function testItemsReturnCorrectNumberOfItems() {
|
||||
$presenter = new GridFieldPresenter();
|
||||
$grid = new GridField('testgrid', 'testgrid', new DataList('GridFieldTest_Person'));
|
||||
$presenter->setGridField($grid);
|
||||
$this->assertEquals(2, $presenter->Items()->count());
|
||||
}
|
||||
|
||||
public function testSorting(){
|
||||
$presenter = new GridFieldPresenter();
|
||||
$GridField = new GridField('testgrid', 'testgrid', new DataList('GridFieldTest_Person'));
|
||||
$presenter->setGridField($GridField);
|
||||
$presenter->sort('Name','desc');
|
||||
$data = $presenter->Items()->map('ID','Name');
|
||||
$this->assertEquals(array(2=>'Second Person', 1=>'First Person'), $data);
|
||||
$presenter->sort('Name','asc');
|
||||
$data = $presenter->Items()->map('ID','Name');
|
||||
$this->assertEquals(array(1=>'First Person', 2=>'Second Person'), $data);
|
||||
}
|
||||
}
|
@ -1,31 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is a Unittest class for DatagridTest
|
||||
* This is a Unittest class for GridFieldTest
|
||||
*
|
||||
*/
|
||||
class DatagridTest extends SapphireTest {
|
||||
class GridFieldTest extends SapphireTest {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
static $fixture_file = 'sapphire/tests/forms/DatagridTest.yml';
|
||||
static $fixture_file = 'sapphire/tests/forms/GridFieldTest.yml';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extraDataObjects = array(
|
||||
'DatagridTest_Person',
|
||||
'GridFieldTest_Person',
|
||||
);
|
||||
|
||||
public function testGetInstance() {
|
||||
$this->assertTrue(new Datagrid('Testgrid') instanceof FormField, 'Datagrid should be a FormField');
|
||||
$this->assertTrue(new GridField('Testgrid') instanceof FormField, 'GridField should be a FormField');
|
||||
}
|
||||
|
||||
public function testSetDataSource() {
|
||||
$grid = new Datagrid('Testgrid');
|
||||
$grid = new GridField('Testgrid');
|
||||
$source = new ArrayList();
|
||||
$grid->setDatasource($source);
|
||||
$this->assertEquals($source, $grid->getDatasource());
|
||||
@ -33,29 +33,29 @@ class DatagridTest extends SapphireTest {
|
||||
|
||||
function testSetEmptyDataPresenter() {
|
||||
$this->setExpectedException('Exception');
|
||||
$grid = new Datagrid('Testgrid');
|
||||
$grid->setDataPresenter('');
|
||||
$grid = new GridField('Testgrid');
|
||||
$grid->setPresenter('');
|
||||
}
|
||||
|
||||
function testSetNonExistingDataPresenter() {
|
||||
$this->setExpectedException('Exception');
|
||||
$grid = new Datagrid('Testgrid');
|
||||
$grid->setDataPresenter('ifThisClassExistsIWouldBeSurprised');
|
||||
$grid = new GridField('Testgrid');
|
||||
$grid->setPresenter('ifThisClassExistsIWouldBeSurprised');
|
||||
}
|
||||
|
||||
function testSetDataPresenterWithDataObject() {
|
||||
$this->setExpectedException('Exception');
|
||||
$grid = new Datagrid('Testgrid');
|
||||
$grid->setDataPresenter('DataObject');
|
||||
$grid = new GridField('Testgrid');
|
||||
$grid->setPresenter('DataObject');
|
||||
}
|
||||
|
||||
function testSetDataPresenter() {
|
||||
$grid = new Datagrid('Testgrid');
|
||||
$grid->setDataPresenter('DatagridPresenter');
|
||||
$grid = new GridField('Testgrid');
|
||||
$grid->setPresenter('GridFieldPresenter');
|
||||
}
|
||||
|
||||
function testSetDataclass() {
|
||||
$grid = new Datagrid('Testgrid');
|
||||
$grid = new GridField('Testgrid');
|
||||
$grid->setModelClass('SiteTree');
|
||||
$this->assertEquals('SiteTree', $grid->getModelClass());
|
||||
}
|
||||
@ -65,23 +65,23 @@ class DatagridTest extends SapphireTest {
|
||||
*/
|
||||
function testFieldHolderWithoutDataSource() {
|
||||
$this->setExpectedException('Exception');
|
||||
$grid = new Datagrid('Testgrid');
|
||||
$grid = new GridField('Testgrid');
|
||||
$this->assertNotNull($grid->FieldHolder());
|
||||
}
|
||||
|
||||
/**
|
||||
* This is better tested in the DatagridFunctionalTest
|
||||
* This is better tested in the GridFieldFunctionalTest
|
||||
*
|
||||
* @see DatagridFunctionalTest
|
||||
* @see GridFieldFunctionalTest
|
||||
*/
|
||||
function testFieldHolder() {
|
||||
$grid = new Datagrid('Testgrid');
|
||||
$grid->setDatasource(new DataList('DatagridTest_Person'));
|
||||
$grid = new GridField('Testgrid');
|
||||
$grid->setDatasource(new DataList('GridFieldTest_Person'));
|
||||
$this->assertNotNull($grid->FieldHolder());
|
||||
}
|
||||
}
|
||||
|
||||
class DatagridTest_Person extends Dataobject implements TestOnly {
|
||||
class GridFieldTest_Person extends Dataobject implements TestOnly {
|
||||
|
||||
public static $db = array(
|
||||
'Name' => 'Varchar'
|
@ -1,4 +1,4 @@
|
||||
DatagridTest_Person:
|
||||
GridFieldTest_Person:
|
||||
first:
|
||||
Name: First Person
|
||||
second:
|
Loading…
Reference in New Issue
Block a user