I'm trying to do something completely different for the SilverStripe website: several subpages have data tables, and each of these tables has its own set of column headers, and some tables have more columns than others. I want to avoid creating tables in the Rich Text Editor, as this is subject to a lot of errors, and this is difficult to handle over time.
I would like to create a DataObject that allows the nth number of columns and the nth number of matching rows. That way, I can invoke a loop (or maybe two) inside the template, where the HTML table structure already exists. Content managers have full control over which columns are in the tables for any sub-page, and they donβt have to worry about supporting customization of the HTML table.
I had several ideas that do not give the results that I want, without a) creating too complicated an interface for content managers and b) the impossibility of correctly binding columns to rows.
I thought about creating a DataObject for table headers, and another for table rows, but then I am puzzled by how to combine them in such a way that it makes sense, especially since there can be any number of columns.
Anyone have any suggestions on this?
UPDATE: Okay, something is happening for me for a TableRowItem data object that can work, and is close to work. However, the problem is this: how to save field values ββin the database when I create them mostly on the fly? As now, the only field that is stored in the database is the field for loading PDF files, everything else is erased when you click "create".
<?php class TruckBodyPdfTableRowItem extends DataObject { private static $db = array( ); // One-to-one relationship with gallery page private static $has_one = array( 'TablePage'=> 'Page', 'TableColumnSet' => 'TableColumnSet', 'PDF' => 'File', ); // tidy up the CMS by not showing these fields public function getCMSFields() { $fields = parent::getCMSFields(); $fields->removeFieldFromTab("Root.Main","TablePageID"); $fields->removeFieldFromTab("Root.Main","TableColumnSetID"); $fields->removeFieldFromTab("Root.Main","SortOrder"); $fields->addFieldsToTab("Root.Main", $this->getMyColumnOptions()); return $fields; } public function getMyColumnOptions() { $columnArray = []; $Columns = DataObject::get('TableColumnSet'); foreach($Columns as $Column){ $columnArray[] = TextField::create($Column->TableColumnHeader); } return $columnArray; } // Tell the datagrid what fields to show in the table private static $summary_fields = array( ); public function canEdit() { return true; } public function canDelete() { return true; } public function canCreate(){ return true; } public function canPublish(){ return true; } public function canView(){ return true; } }
But this is the hard part: determining how to map values ββfrom one DataObject to labels for another, and then automatically generate the nth number of rows based on how many columns have been created.
<?php class TablePage extends Page { private static $db = array( 'H1' => 'varchar(250)', ); private static $has_many = array( 'TableRowItems' => 'TableRowItem', 'TableColumnSets' => 'TableColumnSet' ); private static $has_one = array( ); public function getCMSFields() { $fields = parent::getCMSFields(); $fields->addFieldToTab("Root.Main", new TextField("H1"), "Content"); $gridFieldConfig = GridFieldConfig_RecordEditor::create(); $gridFieldConfig->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
Here are the TableColumnSet and TableRowValue classes. I assumed that there would be one set of column headers associated with the nth number of rows, so I decided that there would be a $has_many relationship between the two classes, since a TableColumnSet can have many table resources, but there will be only one TableColumnSet for all TableRowValues. I was hoping to associate TableRowValues ββwith TableColumnSet values ββusing a drop-down list with all the column headers created, but that just sounds like a bad idea. To manually associate each field in a row with column headings, it seems like tedious and potentially complex content managers.
<?php class TableColumnSet extends DataObject { private static $db = array( 'SortOrder' => 'Int', 'TableColumnHeader'=>'varchar(250)' ); // One-to-one relationship with gallery page private static $has_one = array( 'TablePage'=> 'Page' ); private static $has_many = array( 'TableRowItems' => 'TableRowItem' ); // tidy up the CMS by not showing these fields public function getCMSFields() { $fields = parent::getCMSFields(); $fields->removeFieldFromTab("Root.Main","TablePageID"); $fields->removeFieldFromTab("Root.Main","SortOrder"); return $fields; } // Tell the datagrid what fields to show in the table private static $summary_fields = array( 'TableColumnHeader' => 'Table Column Header', ); public function canEdit() { return true; } public function canDelete() { return true; } public function canCreate(){ return true; } public function canPublish(){ return true; } public function canView(){ return true; } }
I feel there might be something here, at least in relation to the relationship between column headings and rows? I am not sure, however.