Created
May 12, 2020 00:25
-
-
Save tractorcow/1019030afd0fd0c3e9be0b11d0b2c5fc to your computer and use it in GitHub Desktop.
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 | |
namespace App\Forms; | |
use InvalidArgumentException; | |
use LogicException; | |
use SilverStripe\Core\Injector\Injectable; | |
use SilverStripe\Forms\CheckboxField; | |
use SilverStripe\Forms\GridField\GridField; | |
use SilverStripe\Forms\GridField\GridField_ColumnProvider; | |
use SilverStripe\Forms\GridField\GridField_DataManipulator; | |
use SilverStripe\Forms\GridField\GridField_SaveHandler; | |
use SilverStripe\Forms\GridField\GridFieldPaginator; | |
use SilverStripe\ORM\DataObject; | |
use SilverStripe\ORM\DataObjectInterface; | |
use SilverStripe\ORM\Relation; | |
use SilverStripe\ORM\SS_List; | |
use SilverStripe\View\HTML; | |
/** | |
* Lets you use a gridfield in place of a checkbox set field | |
*/ | |
class GridFieldMultiSelector implements GridField_SaveHandler, GridField_ColumnProvider, GridField_DataManipulator | |
{ | |
use Injectable; | |
/** | |
* @skipUpgrade | |
*/ | |
const COLUMN_NAME = 'MultiSelectColumn'; | |
/** | |
* Optional source list | |
* | |
* @var SS_List | |
*/ | |
protected $source = null; | |
/** | |
* @inheritDoc | |
*/ | |
public function augmentColumns($gridField, &$columns) | |
{ | |
// Add "enabled in" column | |
if (in_array(self::COLUMN_NAME, $columns)) { | |
return; | |
} | |
// Add to start | |
array_unshift($columns, self::COLUMN_NAME); | |
} | |
/** | |
* @inheritDoc | |
*/ | |
public function getColumnsHandled($gridField) | |
{ | |
return [self::COLUMN_NAME]; | |
} | |
/** | |
* @param GridField $gridField | |
* @param DataObject $record | |
* @param string $columnName | |
* @return string | |
*/ | |
public function getColumnContent($gridField, $record, $columnName) | |
{ | |
if ($columnName !== self::COLUMN_NAME) { | |
return null; | |
} | |
// Check if this record is in the base (included) list | |
$checked = !!$gridField->getList()->find('ID', $record->ID); | |
// Create checkbox for this locale | |
$checkbox = CheckboxField::create( | |
$this->getFieldName($gridField, $record), | |
false | |
) | |
->setValue($checked) | |
->forTemplate(); | |
return HTML::createTag('label', ['title' => 'Select', 'style' => 'padding: 10px;'], $checkbox); | |
} | |
public function getColumnAttributes($gridField, $record, $columnName) | |
{ | |
return [ | |
'class' => 'col-' . preg_replace('/[^\w]/', '-', $columnName) | |
]; | |
} | |
public function getColumnMetadata($gridField, $columnName) | |
{ | |
return [ | |
'title' => _t(__CLASS__ . '.SELECTED', 'Selected?'), | |
]; | |
} | |
public function handleSave(GridField $gridField, DataObjectInterface $record) | |
{ | |
$value = $gridField->Value(); | |
// Keys for this value will be list of locales to enable | |
$selectedRecordIDs = isset($value[self::COLUMN_NAME]) | |
? array_keys($value[self::COLUMN_NAME]) | |
: []; | |
// Set ID list | |
$gridField->getList()->setByIDList($selectedRecordIDs); | |
} | |
protected function getFieldName(GridField $grid, DataObject $record) | |
{ | |
return sprintf( | |
'%s[%s][%s]', | |
$grid->getName(), | |
self::COLUMN_NAME, | |
$record->ID | |
); | |
} | |
/** | |
* @inheritDoc | |
*/ | |
public function getManipulatedData(GridField $gridField, SS_List $dataList) | |
{ | |
// Check list type | |
if (!$dataList instanceof Relation) { | |
throw new InvalidArgumentException("GridFieldMultiSelector only works with relations"); | |
} | |
// Safe check (todo: Support this in the future?) | |
if ($gridField->getConfig()->getComponentByType(GridFieldPaginator::class)) { | |
throw new LogicException("GridFieldMultiSelector doesn't work with pagination disabled"); | |
} | |
// In order to act as a multi-selector, we need to get the base (unfiltered) records | |
// that the relation belongs to | |
$source = $this->getSource(); | |
if ($source) { | |
return $source; | |
} | |
// Infer source from base datalist | |
$type = $dataList->dataClass(); | |
return DataObject::get($type); | |
} | |
/** | |
* @return SS_List | |
*/ | |
public function getSource() | |
{ | |
return $this->source; | |
} | |
/** | |
* @param SS_List $source | |
* @return $this | |
*/ | |
public function setSource(SS_List $source) | |
{ | |
$this->source = $source; | |
return $this; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment