mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT First cut at data grid with the data presenter
This commit is contained in:
parent
9bd4e752ba
commit
197913842c
@ -12,6 +12,12 @@ class Datagrid extends FormField {
|
||||
*/
|
||||
protected $datasource = null;
|
||||
|
||||
protected $fieldList;
|
||||
|
||||
|
||||
protected $dataPresenterClassName = "DatagridPresenter";
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new datagrid field
|
||||
*
|
||||
@ -20,8 +26,29 @@ class Datagrid extends FormField {
|
||||
* @param SS_list $source
|
||||
* @param Form $form
|
||||
*/
|
||||
function __construct($name, $title = null, SS_list $source = null, Form $form = null) {
|
||||
function __construct($name, $title = null, SS_list $source = null, Form $form = null, $dataPresenterClassName = null) {
|
||||
parent::__construct($name, $title, null, $form);
|
||||
if ($source) $this->setDatasource($source);
|
||||
if ($dataPresenterClassName) $this->dataPresenterClassName = $dataPresenterClassName;
|
||||
$this->setDataPresenter($this->dataPresenterClassName);
|
||||
}
|
||||
|
||||
function setItemClass($itemClass){
|
||||
$this->itemClass = $itemClass;
|
||||
}
|
||||
|
||||
function setDataclass($dataClass){
|
||||
$this->dataClass = $dataClass;
|
||||
}
|
||||
|
||||
function setDataPresenter($dataPresenterClassName){
|
||||
$this->dataPresenter = $dataPresenterClassName;
|
||||
}
|
||||
|
||||
function getDataclass(){
|
||||
if ($this->dataClass) return $this->dataClass;
|
||||
if ($this->datasource->dataClass) return $this->datasource->dataClass;
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,6 +58,7 @@ class Datagrid extends FormField {
|
||||
*/
|
||||
public function setDatasource(SS_List $datasource ) {
|
||||
$this->datasource = $datasource;
|
||||
$this->fieldList = singleton($datasource->dataClass)->summaryFields();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,6 +70,61 @@ class Datagrid extends FormField {
|
||||
return $this->datasource;
|
||||
}
|
||||
|
||||
function FieldList() {
|
||||
return $this->fieldList;
|
||||
}
|
||||
|
||||
|
||||
function FieldHolder() {
|
||||
$dataPresenter = new $this->dataPresenter();
|
||||
$dataPresenter->setDatagrid($this);
|
||||
return $dataPresenter->render();
|
||||
}
|
||||
}
|
||||
|
||||
class DatagridPresenter extends ViewableData {
|
||||
|
||||
/**
|
||||
* @var $template string Template-Overrides
|
||||
*/
|
||||
protected $template = 'DatagridPresenter';
|
||||
/**
|
||||
* @var $itemClass string Class name for each item/row
|
||||
*/
|
||||
protected $itemClass = 'DatagridPresenter_Item';
|
||||
|
||||
protected $datagrid = null;
|
||||
|
||||
public $fieldCasting = array();
|
||||
|
||||
public $fieldFormatting = array();
|
||||
|
||||
|
||||
function setTemplate($template){
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
public function setDatagrid(Datagrid $datagrid){
|
||||
$this->datagrid = $datagrid;
|
||||
}
|
||||
|
||||
public function getDatagrid(){
|
||||
return $this->datagrid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a DataObjectSet of Datagrid_Item objects, suitable for display in the template.
|
||||
*/
|
||||
function Items() {
|
||||
$fieldItems = new ArrayList();
|
||||
if($items = $this->datagrid->datasource) {
|
||||
foreach($items as $item) {
|
||||
if($item) $fieldItems->push(new $this->itemClass($item, $this));
|
||||
}
|
||||
}
|
||||
return $fieldItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the headers or column names for this grid
|
||||
*
|
||||
@ -53,10 +136,16 @@ class Datagrid extends FormField {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders() {
|
||||
|
||||
if($this->datasource instanceof DataList ) {
|
||||
return singleton($this->datasource->dataClass)->summaryFields();
|
||||
public function Headers() {
|
||||
if($this->datagrid->datasource instanceof DataList ) {
|
||||
$fieldHeaders = new ArrayList();
|
||||
$fieldHeadersSummaryFields = singleton($this->datagrid->datasource->dataClass)->summaryFields();
|
||||
if (is_array($fieldHeadersSummaryFields)){
|
||||
foreach ($fieldHeadersSummaryFields as $name=>$title){
|
||||
$fieldHeaders->push(new ArrayData(array('Name'=>$name, 'Title'=>$title)));
|
||||
}
|
||||
}
|
||||
return $fieldHeaders;
|
||||
} else {
|
||||
$firstItem = $this->datasource->first();
|
||||
if(!$firstItem) {
|
||||
@ -65,4 +154,106 @@ class Datagrid extends FormField {
|
||||
return array_combine(array_keys($firstItem),array_keys($firstItem));
|
||||
}
|
||||
}
|
||||
|
||||
function setFieldCasting($casting) {
|
||||
$this->fieldCasting = $casting;
|
||||
}
|
||||
|
||||
function setFieldFormatting($formatting) {
|
||||
$this->fieldFormatting = $formatting;
|
||||
}
|
||||
|
||||
|
||||
function render(){
|
||||
return $this->renderWith(array($this->template));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A single record in a Datagrid.
|
||||
* @package forms
|
||||
* @see Datagrid
|
||||
*/
|
||||
class DatagridPresenter_Item extends ViewableData {
|
||||
|
||||
/**
|
||||
* @var DataObject The underlying data record,
|
||||
* usually an element of {@link Datagrid->datasource()}.
|
||||
*/
|
||||
protected $item;
|
||||
|
||||
/**
|
||||
* @var Datagrid
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
function ID() {
|
||||
return $this->item->ID;
|
||||
}
|
||||
|
||||
function Parent() {
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
function __construct($item, $parent) {
|
||||
$this->failover = $this->item = $item;
|
||||
$this->parent = $parent;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
function Fields($xmlSafe = true) {
|
||||
$list = $this->parent->getDatagrid()->FieldList();
|
||||
foreach($list as $fieldName => $fieldTitle) {
|
||||
$value = "";
|
||||
|
||||
// TODO Delegates that to DataList
|
||||
// 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';
|
||||
if($j == sizeof($fieldNameParts)-1) {
|
||||
if($tmpItem) $value = $tmpItem->$relationMethod;
|
||||
} else {
|
||||
if($tmpItem) $tmpItem = $tmpItem->$relationMethod();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// casting
|
||||
if(array_key_exists($fieldName, $this->parent->fieldCasting)) {
|
||||
$value = $this->parent->getCastedValue($value, $this->parent->fieldCasting[$fieldName]);
|
||||
} elseif(is_object($value) && method_exists($value, 'Nice')) {
|
||||
$value = $value->Nice();
|
||||
}
|
||||
|
||||
// formatting
|
||||
$item = $this->item;
|
||||
if(array_key_exists($fieldName, $this->parent->fieldFormatting)) {
|
||||
$format = str_replace('$value', "__VAL__", $this->parent->fieldFormatting[$fieldName]);
|
||||
$format = preg_replace('/\$([A-Za-z0-9-_]+)/','$item->$1', $format);
|
||||
$format = str_replace('__VAL__', '$value', $format);
|
||||
eval('$value = "' . $format . '";');
|
||||
}
|
||||
|
||||
//escape
|
||||
if($escape = $this->parent->getDatagrid()->fieldEscape){
|
||||
foreach($escape as $search => $replace){
|
||||
$value = str_replace($search, $replace, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$fields[] = new ArrayData(array(
|
||||
"Name" => $fieldName,
|
||||
"Title" => $fieldTitle,
|
||||
"Value" => $value
|
||||
));
|
||||
}
|
||||
return new ArrayList($fields);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<% control Headings %>
|
||||
<th class="<% if FirstLast %>ss-datagrid-{$FirstLast} <% if IsSortable %>ss-datagrid-sortable<% end_if %> <% if IsSorted %>ss-datagrid-sorted ss-datagrid-{$SortedDirection}">
|
||||
<% 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 %>">
|
||||
$Title <span class="ui-icon"></span></th>
|
||||
<% end_control %>
|
||||
</tr>
|
@ -6,13 +6,28 @@
|
||||
*/
|
||||
class DatagridFunctionalTest extends FunctionalTest {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
static $fixture_file = 'sapphire/tests/forms/DatagridTest.yml';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extraDataObjects = array(
|
||||
'DatagridTest_Person',
|
||||
);
|
||||
|
||||
public function testGetInstance() {
|
||||
$this->assertTrue(new Datagrid('testgrid') instanceof Datagrid, 'Trying to find an instance of Datagrid.');
|
||||
}
|
||||
|
||||
public function testAddToForm() {
|
||||
$firstPerson = $this->objFromFixture('DatagridTest_Person', 'first');
|
||||
$response = $this->get("DatagridFunctionalTest_Controller/");
|
||||
$this->assertContains("form", $response->getBody());
|
||||
$this->assertContains($firstPerson->Name, $response->getBody());
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +35,8 @@ class DatagridFunctionalTest_Controller extends ContentController {
|
||||
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user