Last active
December 18, 2015 11:19
-
-
Save willmorgan/5774423 to your computer and use it in GitHub Desktop.
3,1 DataObjectManager style field that allows arbitrary options to be rendered on the frontend with maximum flexibility and ease.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* TableOptionsetField | |
* DataObjectManager style field that allows arbitrary options to be rendered on | |
* the frontend with maximum flexibility and ease. | |
* @author Will Morgan <[email protected]> | |
*/ | |
class TableOptionsetField extends FormField { | |
/** | |
* @var SS_List $source The iterable data source | |
*/ | |
protected $source; | |
/** | |
* @var array A hash of field => title column names, to be used in rendering | |
*/ | |
protected $sourceColumns; | |
/** | |
* @var callable A function that is run to get the value of a source item | |
*/ | |
protected $sourceValueGetter; | |
/** | |
* @var string The HTML attribute name to determine input selection | |
*/ | |
protected static $selected_attr = 'checked'; | |
public function __construct($name, $title = null, $source, $sourceColumns = null, $sourceValueGetter = null, $value = null, $form = null) { | |
parent::__construct($name, $title, $value); | |
$this | |
->setSource($source) | |
->setSourceColumns($sourceColumns) | |
->setSourceValueGetter($sourceValueGetter) | |
->setForm($form); | |
} | |
/** | |
* @return SS_List | |
*/ | |
public function getSource() { | |
return $this->source; | |
} | |
public function setSource(SS_List $source) { | |
$this->source = $source; | |
return $this; | |
} | |
public function getSourceColumns() { | |
return $this->sourceColumns; | |
} | |
public function setSourceColumns(array $columns) { | |
$this->sourceColumns = $columns; | |
return $this; | |
} | |
/** | |
* @param callable $callable The function to call on the source object. | |
*/ | |
public function setSourceValueGetter($callable) { | |
if(!is_null($callable) && !is_callable($callable)) { | |
throw new InvalidArgumentException('Must be a callable: ' . var_export($callable, true)); | |
} | |
$this->sourceValueGetter = $callable; | |
return $this; | |
} | |
/** | |
* Gets the HTML attributes for the input field. | |
* @return string | |
*/ | |
public function getFieldAttrs($source) { | |
$sourceValue = $this->getSourceValue($source); | |
$attrs = array( | |
'id' => sprintf('%s_%s', $this->ID(), $sourceValue), | |
'name' => $this->getName(), | |
'value' => $sourceValue, | |
static::$selected_attr => $this->isSourceSelected($source), | |
); | |
return $this->getAttributesHTML($attrs); | |
} | |
/** | |
* @return boolean Whether this source is selected in the field | |
*/ | |
public function isSourceSelected($source) { | |
return $this->dataValue() == $this->getSourceValue($source); | |
} | |
/** | |
* @return string The "value" to use for this source item. | |
*/ | |
public function getSourceValue($source) { | |
// 99% of the time... | |
if(!$this->sourceValueGetter && $source instanceof DataObject) { | |
return $source->ID; | |
} | |
return $this->sourceValueGetter($source); | |
} | |
/** | |
* Prepares data for the view to render in to a table. | |
* @return string | |
*/ | |
public function Field($properties = array()) { | |
$options = array(); | |
$columns = $this->getSourceColumns(); | |
// 99% of the time it'll be a DataList, so use convention! | |
if($this->getSource() instanceof DataList && empty($columns)) { | |
$colClass = $this->getSource()->dataClass(); | |
$columns = $colClass::config()->get('summary_fields'); | |
} | |
foreach($this->getSource() as $id => $sourceObject) { | |
$fields = array(); | |
foreach($columns as $colName => $colTitle) { | |
if($sourceObject->hasMethod($colName)) { | |
$value = $sourceObject->$colName(); | |
} | |
else { | |
$value = $sourceObject->getField($colName); | |
} | |
$fields[] = array('Value' => $value); | |
} | |
$options[] = array( | |
'Object' => $sourceObject, | |
'FieldAttrs' => $this->getFieldAttrs($sourceObject), | |
'Fields' => new ArrayList($fields), | |
); | |
} | |
$viewColumns = array(); | |
// Convert these in to template-friendly variables | |
foreach($columns as $field => $title) { | |
$viewColumns[] = array( | |
'Field' => $field, | |
'Title' => $title, | |
); | |
} | |
$tplOptions = array_merge($properties, array( | |
'Columns' => new ArrayList($viewColumns), | |
'Options' => new ArrayList($options), | |
)); | |
return $this->customise($tplOptions)->renderWith( | |
$this->getTemplates() | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<table> | |
<tr> | |
<td></td> | |
<% loop $Columns %> | |
<th>$Title</th> | |
<% end_loop %> | |
</tr> | |
<% loop $Options %> | |
<tr> | |
<td><input type="radio" $FieldAttrs></td> | |
<% loop $Fields %> | |
<td>$Value</td> | |
<% end_loop %> | |
</tr> | |
<% end_loop %> | |
</table> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment