BUG Fix inline editing / sortable

This commit is contained in:
Damian Mooyman 2017-09-15 16:01:32 +12:00
parent b07079d758
commit 9421e85483
3 changed files with 68 additions and 18 deletions

View File

@ -8,7 +8,9 @@ use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridField_HTMLProvider; use SilverStripe\Forms\GridField\GridField_HTMLProvider;
use SilverStripe\Forms\GridField\GridField_SaveHandler; use SilverStripe\Forms\GridField\GridField_SaveHandler;
use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface; use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\ManyManyList; use SilverStripe\ORM\ManyManyList;
use SilverStripe\View\ArrayData; use SilverStripe\View\ArrayData;
use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Injector\Injector;
@ -20,6 +22,10 @@ use Exception;
*/ */
class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_SaveHandler class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_SaveHandler
{ {
/**
* @skipUpgrade
*/
const POST_KEY = 'GridFieldAddNewInlineButton';
private $fragment; private $fragment;
@ -86,7 +92,9 @@ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_S
$fragment = $this->getFragment(); $fragment = $this->getFragment();
if (!$editable = $grid->getConfig()->getComponentByType(GridFieldEditableColumns::class)) { /** @var GridFieldEditableColumns $editable */
$editable = $grid->getConfig()->getComponentByType(GridFieldEditableColumns::class);
if (!$editable) {
throw new Exception('Inline adding requires the editable columns component'); throw new Exception('Inline adding requires the editable columns component');
} }
@ -122,7 +130,7 @@ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_S
$field->setName(sprintf( $field->setName(sprintf(
'%s[%s][{%%=o.num%%}][%s]', '%s[%s][{%%=o.num%%}][%s]',
$grid->getName(), $grid->getName(),
__CLASS__, self::POST_KEY,
$field->getName() $field->getName()
)); ));
@ -132,10 +140,13 @@ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_S
// Convert GridFieldEditableColumns to the template format // Convert GridFieldEditableColumns to the template format
$content = str_replace( $content = str_replace(
'[GridFieldEditableColumns][0]', sprintf('[%s][0]', GridFieldEditableColumns::POST_KEY),
'[GridFieldAddNewInlineButton][{%=o.num%}]', sprintf('[%s][{%%=o.num%%}]', self::POST_KEY),
$content $content
); );
// Cast content as HTML
$content = DBField::create_field('HTMLFragment', $content);
} }
$attrs = ''; $attrs = '';
@ -159,22 +170,23 @@ class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_S
$list = $grid->getList(); $list = $grid->getList();
$value = $grid->Value(); $value = $grid->Value();
if (!isset($value[__CLASS__]) || !is_array($value[__CLASS__])) { if (!isset($value[self::POST_KEY]) || !is_array($value[self::POST_KEY])) {
return; return;
} }
$class = $grid->getModelClass(); $class = $grid->getModelClass();
/** @var GridFieldEditableColumns $editable */ /** @var GridFieldEditableColumns $editable */
$editable = $grid->getConfig()->getComponentByType('Symbiote\\GridFieldExtensions\\GridFieldEditableColumns'); $editable = $grid->getConfig()->getComponentByType(GridFieldEditableColumns::class);
/** @var GridFieldOrderableRows $sortable */ /** @var GridFieldOrderableRows $sortable */
$sortable = $grid->getConfig()->getComponentByType('Symbiote\\GridFieldExtensions\\GridFieldOrderableRows'); $sortable = $grid->getConfig()->getComponentByType(GridFieldOrderableRows::class);
$form = $editable->getForm($grid, $record); $form = $editable->getForm($grid, $record);
if (!singleton($class)->canCreate()) { if (!singleton($class)->canCreate()) {
return; return;
} }
foreach ($value[__CLASS__] as $fields) { foreach ($value[self::POST_KEY] as $fields) {
/** @var DataObject $item */
$item = $class::create(); $item = $class::create();
$extra = array(); $extra = array();

View File

@ -3,6 +3,7 @@
namespace Symbiote\GridFieldExtensions; namespace Symbiote\GridFieldExtensions;
use SilverStripe\Control\Controller; use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse_Exception; use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Core\ClassInfo; use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config; use SilverStripe\Core\Config\Config;
@ -11,6 +12,7 @@ use SilverStripe\Forms\DropdownField;
use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridField_HTMLProvider; use SilverStripe\Forms\GridField\GridField_HTMLProvider;
use SilverStripe\Forms\GridField\GridField_URLHandler; use SilverStripe\Forms\GridField\GridField_URLHandler;
use SilverStripe\Forms\GridField\GridFieldDetailForm;
use SilverStripe\View\ArrayData; use SilverStripe\View\ArrayData;
use ReflectionClass; use ReflectionClass;
use Exception; use Exception;
@ -23,6 +25,10 @@ use Exception;
*/ */
class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URLHandler class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URLHandler
{ {
/**
* @skipUpgrade
*/
const POST_KEY = 'GridFieldAddNewMultiClass';
private static $allowed_actions = array( private static $allowed_actions = array(
'handleAdd' 'handleAdd'
@ -35,8 +41,14 @@ class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URL
private $title; private $title;
/**
* @var array
*/
private $classes; private $classes;
/**
* @var string
*/
private $defaultClass; private $defaultClass;
/** /**
@ -157,6 +169,7 @@ class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URL
* Sets the classes that can be created using this button. * Sets the classes that can be created using this button.
* *
* @param array $classes a set of class names, optionally mapped to titles * @param array $classes a set of class names, optionally mapped to titles
* @param string $default
* @return GridFieldAddNewMultiClass $this * @return GridFieldAddNewMultiClass $this
*/ */
public function setClasses(array $classes, $default = null) public function setClasses(array $classes, $default = null)
@ -184,14 +197,17 @@ class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URL
* Handles adding a new instance of a selected class. * Handles adding a new instance of a selected class.
* *
* @param GridField $grid * @param GridField $grid
* @param SS_HTTPRequest $request * @param HTTPRequest $request
* @return GridFieldAddNewMultiClassHandler * @return GridFieldAddNewMultiClassHandler
* @throws Exception
* @throws HTTPResponse_Exception
*/ */
public function handleAdd($grid, $request) public function handleAdd($grid, $request)
{ {
$class = $request->param('ClassName'); $class = $request->param('ClassName');
$classes = $this->getClasses($grid); $classes = $this->getClasses($grid);
$component = $grid->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldDetailForm'); /** @var GridFieldDetailForm $component */
$component = $grid->getConfig()->getComponentByType(GridFieldDetailForm::class);
if (!$component) { if (!$component) {
throw new Exception('The add new multi class component requires the detail form component.'); throw new Exception('The add new multi class component requires the detail form component.');
@ -228,7 +244,7 @@ class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URL
GridFieldExtensions::include_requirements(); GridFieldExtensions::include_requirements();
$field = new DropdownField(sprintf('%s[ClassName]', __CLASS__), '', $classes, $this->defaultClass); $field = new DropdownField(sprintf('%s[ClassName]', self::POST_KEY), '', $classes, $this->defaultClass);
if (Config::inst()->get(__CLASS__, 'showEmptyString')) { if (Config::inst()->get(__CLASS__, 'showEmptyString')) {
$field->setEmptyString(_t('GridFieldExtensions.SELECTTYPETOCREATE', '(Select type to create)')); $field->setEmptyString(_t('GridFieldExtensions.SELECTTYPETOCREATE', '(Select type to create)'));
} }
@ -263,6 +279,8 @@ class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URL
/** /**
* Sanitise a model class' name for inclusion in a link * Sanitise a model class' name for inclusion in a link
*
* @param string $class
* @return string * @return string
*/ */
protected function sanitiseClassName($class) protected function sanitiseClassName($class)
@ -272,6 +290,8 @@ class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URL
/** /**
* Unsanitise a model class' name from a URL param * Unsanitise a model class' name from a URL param
*
* @param string $class
* @return string * @return string
*/ */
protected function unsanitiseClassName($class) protected function unsanitiseClassName($class)

View File

@ -2,7 +2,9 @@
namespace Symbiote\GridFieldExtensions; namespace Symbiote\GridFieldExtensions;
use Closure;
use SilverStripe\Control\Controller; use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse_Exception; use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forms\FieldList; use SilverStripe\Forms\FieldList;
@ -13,8 +15,11 @@ use SilverStripe\Forms\GridField\GridFieldDataColumns;
use SilverStripe\Forms\GridField\GridField_HTMLProvider; use SilverStripe\Forms\GridField\GridField_HTMLProvider;
use SilverStripe\Forms\GridField\GridField_SaveHandler; use SilverStripe\Forms\GridField\GridField_SaveHandler;
use SilverStripe\Forms\GridField\GridField_URLHandler; use SilverStripe\Forms\GridField\GridField_URLHandler;
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
use SilverStripe\Forms\LiteralField; use SilverStripe\Forms\LiteralField;
use SilverStripe\Forms\ReadonlyField; use SilverStripe\Forms\ReadonlyField;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface; use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\ManyManyList; use SilverStripe\ORM\ManyManyList;
use Exception; use Exception;
@ -34,6 +39,10 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
GridField_SaveHandler, GridField_SaveHandler,
GridField_URLHandler GridField_URLHandler
{ {
/**
* @skipUpgrade
*/
const POST_KEY = 'GridFieldEditableColumns';
private static $allowed_actions = array( private static $allowed_actions = array(
'handleForm' 'handleForm'
@ -104,19 +113,20 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
public function handleSave(GridField $grid, DataObjectInterface $record) public function handleSave(GridField $grid, DataObjectInterface $record)
{ {
/** @var DataList $list */
$list = $grid->getList(); $list = $grid->getList();
$value = $grid->Value(); $value = $grid->Value();
if (!isset($value[__CLASS__]) || !is_array($value[__CLASS__])) { if (!isset($value[self::POST_KEY]) || !is_array($value[self::POST_KEY])) {
return; return;
} }
/** @var GridFieldOrderableRows $sortable */ /** @var GridFieldOrderableRows $sortable */
$sortable = $grid->getConfig()->getComponentByType('Symbiote\\GridFieldExtensions\\GridFieldOrderableRows'); $sortable = $grid->getConfig()->getComponentByType(GridFieldOrderableRows::class);
$form = $this->getForm($grid, $record); $form = $this->getForm($grid, $record);
foreach ($value[__CLASS__] as $id => $fields) { foreach ($value[self::POST_KEY] as $id => $fields) {
if (!is_numeric($id) || !is_array($fields)) { if (!is_numeric($id) || !is_array($fields)) {
continue; continue;
} }
@ -147,6 +157,12 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
} }
} }
/**
* @param GridField $grid
* @param HTTPRequest $request
* @return Form
* @throws HTTPResponse_Exception
*/
public function handleForm(GridField $grid, $request) public function handleForm(GridField $grid, $request)
{ {
$id = $request->param('ID'); $id = $request->param('ID');
@ -182,12 +198,14 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
* @param GridField $grid * @param GridField $grid
* @param DataObjectInterface $record * @param DataObjectInterface $record
* @return FieldList * @return FieldList
* @throws Exception
*/ */
public function getFields(GridField $grid, DataObjectInterface $record) public function getFields(GridField $grid, DataObjectInterface $record)
{ {
$cols = $this->getDisplayFields($grid); $cols = $this->getDisplayFields($grid);
$fields = new FieldList(); $fields = new FieldList();
/** @var DataList $list */
$list = $grid->getList(); $list = $grid->getList();
$class = $list ? $list->dataClass() : null; $class = $list ? $list->dataClass() : null;
@ -200,7 +218,7 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
if (isset($info['callback'])) { if (isset($info['callback'])) {
$field = call_user_func($info['callback'], $record, $col, $grid); $field = call_user_func($info['callback'], $record, $col, $grid);
} elseif (isset($info['field'])) { } elseif (isset($info['field'])) {
if ($info['field'] == 'SilverStripe\\Forms\\LiteralField') { if ($info['field'] == LiteralField::class) {
$field = new $info['field']($col, null); $field = new $info['field']($col, null);
} else { } else {
$field = new $info['field']($col); $field = new $info['field']($col);
@ -234,12 +252,12 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
// available or is readonly // available or is readonly
// //
$colRelation = explode('.', $col); $colRelation = explode('.', $col);
if ($class && $obj = singleton($class)->dbObject($colRelation[0])) { if ($class && $obj = DataObject::singleton($class)->dbObject($colRelation[0])) {
$field = $obj->scaffoldFormField(); $field = $obj->scaffoldFormField();
} else { } else {
$field = new ReadonlyField($colRelation[0]); $field = new ReadonlyField($colRelation[0]);
} }
} elseif ($class && $obj = singleton($class)->dbObject($col)) { } elseif ($class && $obj = DataObject::singleton($class)->dbObject($col)) {
$field = $obj->scaffoldFormField(); $field = $obj->scaffoldFormField();
} else { } else {
$field = new ReadonlyField($col); $field = new ReadonlyField($col);
@ -292,7 +310,7 @@ class GridFieldEditableColumns extends GridFieldDataColumns implements
return sprintf( return sprintf(
'%s[%s][%s][%s]', '%s[%s][%s][%s]',
$grid->getName(), $grid->getName(),
__CLASS__, self::POST_KEY,
$record->ID, $record->ID,
$name $name
); );