Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port betterbuttons to framework #8569

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions _config/buttons.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
Name: buttons
---
SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest:
formActions:
showPagination: true
showAdd: true
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,27 @@ SilverStripe\Admin\LeftAndMain:
'Feedback': ''
```

## Customising the CMS form actions

The `Previous`, `Next` and `Add` actions on the edit form are visible by default but can be hidden globally by adding the following `.yml` config:

```yml
SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest:
formActions:
showPagination: false
showAdd: false
```

You can also override this for a specific `GridField` instance when using the `GridFieldConfig_RecordEditor` constructor:

```php
$grid = new GridField(
"pages",
"All Pages",
SiteTree::get(),
GridFieldConfig_RecordEditor::create(null, false, false));
```

## Related

* [How to extend the CMS interface](extend_cms_interface)
6 changes: 4 additions & 2 deletions src/Forms/GridField/GridFieldConfig_RecordEditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ class GridFieldConfig_RecordEditor extends GridFieldConfig
/**
*
* @param int $itemsPerPage - How many items per page should show up
* @param bool $showPagination Whether the `Previous` and `Next` buttons should display or not, leave as null to use default
* @param bool $showAdd Whether the `Add` button should display or not, leave as null to use default
*/
public function __construct($itemsPerPage = null)
public function __construct($itemsPerPage = null, $showPagination = null, $showAdd = null)
{
parent::__construct();

Expand All @@ -26,7 +28,7 @@ public function __construct($itemsPerPage = null)
$this->addComponent(new GridField_ActionMenu());
$this->addComponent(new GridFieldPageCount('toolbar-header-right'));
$this->addComponent($pagination = new GridFieldPaginator($itemsPerPage));
$this->addComponent(new GridFieldDetailForm());
$this->addComponent(new GridFieldDetailForm(null, $showPagination, $showAdd));

$sort->setThrowExceptionOnBadDataType(false);
$filter->setThrowExceptionOnBadDataType(false);
Expand Down
91 changes: 85 additions & 6 deletions src/Forms/GridField/GridFieldDetailForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,20 @@ class GridFieldDetailForm implements GridField_URLHandler
protected $template = null;

/**
*
* @var string
*/
protected $name;

/**
* @var bool
*/
protected $showPagination;

/**
* @var bool
*/
protected $showAdd;

/**
* @var Validator The form validator used for both add and edit fields.
*/
Expand Down Expand Up @@ -79,10 +88,14 @@ public function getURLHandlers($gridField)
* controller who wants to display the getCMSFields
*
* @param string $name The name of the edit form to place into the pop-up form
* @param bool $showPagination Whether the `Previous` and `Next` buttons should display or not, leave as null to use default
* @param bool $showAdd Whether the `Add` button should display or not, leave as null to use default
*/
public function __construct($name = 'DetailForm')
public function __construct($name = null, $showPagination = null, $showAdd = null)
{
$this->name = $name;
$this->setName($name ?: 'DetailForm');
$this->setShowPagination($showPagination);
$this->setShowAdd($showAdd);
}

/**
Expand All @@ -93,6 +106,10 @@ public function __construct($name = 'DetailForm')
*/
public function handleItem($gridField, $request)
{
if ($gridStateStr = $request->getVar('gridState')) {
$gridField->getState(false)->setValue($gridStateStr);
}

// Our getController could either give us a true Controller, if this is the top-level GridField.
// It could also give us a RequestHandler in the form of GridFieldDetailForm_ItemRequest if this is a
// nested GridField.
Expand All @@ -102,7 +119,7 @@ public function handleItem($gridField, $request)
if (is_numeric($request->param('ID'))) {
/** @var Filterable $dataList */
$dataList = $gridField->getList();
$record = $dataList->byID($request->param("ID"));
$record = $dataList->byID($request->param('ID'));
} else {
$record = Injector::inst()->create($gridField->getModelClass());
}
Expand Down Expand Up @@ -179,6 +196,68 @@ public function getName()
return $this->name;
}

/**
* @return bool
*/
protected function getDefaultShowPagination()
{
$formActionsConfig = GridFieldDetailForm_ItemRequest::config()->get('formActions');
return isset($formActionsConfig['showPagination']) ? (boolean) $formActionsConfig['showPagination'] : false;
}

/**
* @return bool
*/
public function getShowPagination()
{
if ($this->showPagination === null) {
return $this->getDefaultShowPagination();
}

return (boolean) $this->showPagination;
}

/**
* @param bool|null $showPagination
* @return GridFieldDetailForm
*/
public function setShowPagination($showPagination)
{
$this->showPagination = $showPagination;
return $this;
}

/**
* @return bool
*/
protected function getDefaultShowAdd()
{
$formActionsConfig = GridFieldDetailForm_ItemRequest::config()->get('formActions');
return isset($formActionsConfig['showAdd']) ? (boolean) $formActionsConfig['showAdd'] : false;
}

/**
* @return bool
*/
public function getShowAdd()
{
if ($this->showAdd === null) {
return $this->getDefaultShowAdd();
}

return (boolean) $this->showAdd;
}

/**
* @param bool|null $showAdd
* @return GridFieldDetailForm
*/
public function setShowAdd($showAdd)
{
$this->showAdd = $showAdd;
return $this;
}

bergice marked this conversation as resolved.
Show resolved Hide resolved
/**
* @param Validator $validator
* @return $this
Expand Down Expand Up @@ -232,8 +311,8 @@ public function getItemRequestClass()
{
if ($this->itemRequestClass) {
return $this->itemRequestClass;
} elseif (ClassInfo::exists(static::class . "_ItemRequest")) {
return static::class . "_ItemRequest";
} elseif (ClassInfo::exists(static::class . '_ItemRequest')) {
return static::class . '_ItemRequest';
} else {
return GridFieldDetailForm_ItemRequest::class;
}
Expand Down
151 changes: 151 additions & 0 deletions src/Forms/GridField/GridFieldDetailForm_ItemRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Control\RequestHandler;
use SilverStripe\Core\Config\Config;
use SilverStripe\Forms\CompositeField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\HiddenField;
use SilverStripe\Forms\LiteralField;
use SilverStripe\ORM\ArrayList;
use SilverStripe\ORM\DataObject;
Expand Down Expand Up @@ -278,6 +281,7 @@ protected function getFormActions()
$canEdit = $this->record->canEdit();
$canDelete = $this->record->canDelete();
$actions = new FieldList();

if ($this->record->ID !== 0) {
if ($canEdit) {
$actions->push(FormAction::create('doSave', _t('SilverStripe\\Forms\\GridField\\GridFieldDetailForm.Save', 'Save'))
Expand All @@ -290,6 +294,45 @@ protected function getFormActions()
->setUseButtonTag(true)
->addExtraClass('btn-outline-danger btn-hide-outline font-icon-trash-bin action--delete'));
}

$gridStateStr = $this->getRequest()->requestVar('gridState');

$this->gridField->getState(false)->setValue($gridStateStr);
$actions->push(HiddenField::create('gridState', null, $gridStateStr));

bergice marked this conversation as resolved.
Show resolved Hide resolved
$rightGroup = CompositeField::create()->setName('RightGroup');
$rightGroup->addExtraClass('right');
$rightGroup->setFieldHolderTemplate(get_class($rightGroup) . '_holder_buttongroup');

$previousAndNextGroup = CompositeField::create()->setName('PreviousAndNextGroup');
$previousAndNextGroup->addExtraClass('rounded');
$previousAndNextGroup->setFieldHolderTemplate(get_class($previousAndNextGroup) . '_holder_buttongroup');


$component = $this->gridField->getConfig()->getComponentByType(GridFieldDetailForm::class);

if ($component->getShowPagination()) {
$previousAndNextGroup->push(FormAction::create('doPrevious')
->setUseButtonTag(true)
->setAttribute('data-grid-state', $gridStateStr)
->setDisabled(!$this->getPreviousRecordID())
->addExtraClass('btn btn-secondary font-icon-left-open action--previous discard-confirmation'));

$previousAndNextGroup->push(FormAction::create('doNext')
->setUseButtonTag(true)
->setAttribute('data-grid-state', $gridStateStr)
->setDisabled(!$this->getNextRecordID())
->addExtraClass('btn btn-secondary font-icon-right-open action--next discard-confirmation'));
}

$rightGroup->push($previousAndNextGroup);

if ($component->getShowAdd()) {
$rightGroup->push(FormAction::create('doNew')
->setUseButtonTag(true)
->setAttribute('data-grid-state', $this->getRequest()->getVar('gridState'))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

->addExtraClass('btn btn-primary font-icon-plus rounded action--new discard-confirmation'));
}
} else { // adding new record
//Change the Save label to 'Create'
$actions->push(FormAction::create('doSave', _t('SilverStripe\\Forms\\GridField\\GridFieldDetailForm.Create', 'Create'))
Expand All @@ -309,7 +352,13 @@ protected function getFormActions()
$actions->push(new LiteralField('cancelbutton', $text));
}
}

$this->extend('updateFormActions', $actions);

if (isset($rightGroup)) {
$actions->push($rightGroup);
}

return $actions;
}

Expand Down Expand Up @@ -410,6 +459,108 @@ public function doSave($data, $form)
return $this->redirectAfterSave($isNewRecord);
}

/**
* Goes to the previous record
* @param array $data The form data
* @param Form $form The Form object
* @return HTTPResponse
*/
public function doPrevious($data, $form)
{
$this->getToplevelController()->getResponse()->addHeader('X-Pjax', 'Content');
$link = $this->getEditLink($this->getPreviousRecordID());
return $this->redirect($link);
}

/**
* Goes to the next record
* @param array $data The form data
* @param Form $form The Form object
* @return HTTPResponse
*/
public function doNext($data, $form)
{
$this->getToplevelController()->getResponse()->addHeader('X-Pjax', 'Content');
$link = $this->getEditLink($this->getNextRecordID());
return $this->redirect($link);
}

/**
* Creates a new record. If you're already creating a new record,
* this forces the URL to change.
*
* @param array $data The form data
* @param Form $form The Form object
* @return HTTPResponse
*/
public function doNew($data, $form)
{
return $this->redirect(Controller::join_links($this->gridField->Link('item'), 'new'));
}

/**
* Gets the edit link for a record
*
* @param int $id The ID of the record in the GridField
* @return string
*/
public function getEditLink($id)
{
return Controller::join_links(
$this->gridField->Link(),
'item',
$id,
'?gridState=' . urlencode($this->gridField->getState(false)->Value())
);
}

/**
* @param int $offset The offset from the current record
* @return int|bool
*/
private function getAdjacentRecordID($offset)
{
$gridField = $this->getGridField();
$gridStateStr = $this->getRequest()->requestVar('gridState');
$state = $gridField->getState(false);
$state->setValue($gridStateStr);
$data = $state->getData();
$paginator = $data->getData('GridFieldPaginator');
if (!$paginator) {
return false;
}

$currentPage = $data->getData('GridFieldPaginator')->getData('currentPage');
$itemsPerPage = $data->getData('GridFieldPaginator')->getData('itemsPerPage');

$limit = $itemsPerPage + 2;
$limitOffset = max(0, $itemsPerPage * ($currentPage-1) -1);

$map = $gridField->getManipulatedList()->limit($limit, $limitOffset)->column('ID');
$index = array_search($this->record->ID, $map);
return isset($map[$index+$offset]) ? $map[$index+$offset] : false;
}

/**
* Gets the ID of the previous record in the list.
*
* @return int
*/
public function getPreviousRecordID()
{
return $this->getAdjacentRecordID(-1);
}

/**
* Gets the ID of the next record in the list.
*
* @return int
*/
public function getNextRecordID()
{
return $this->getAdjacentRecordID(1);
}

/**
* Response object for this request after a successful save
*
Expand Down
7 changes: 6 additions & 1 deletion src/Forms/GridField/GridFieldEditButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,12 @@ public function getExtraData($gridField, $record, $columnName)
*/
public function getUrl($gridField, $record, $columnName)
{
return Controller::join_links($gridField->Link('item'), $record->ID, 'edit');
return Controller::join_links(
$gridField->Link('item'),
$record->ID,
'edit',
'?gridState=' . urlencode($gridField->getState(false)->Value())
);
}

/**
Expand Down
Loading