Skip to content

Commit

Permalink
MINOR: Add Previous, Next and Create New actions in edit form
Browse files Browse the repository at this point in the history
If the form is opened via a grid field, the filters will be retained so the previous/next record opened will be correct
  • Loading branch information
bergice committed Nov 5, 2018
1 parent 511c368 commit 8a8a0dc
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 1 deletion.
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
---
FormActions:
showPrevious: true
showNext: true
showAdd: true
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ 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 by adding the following `.yml` config:

```yml
FormActions:
showPrevious: false
showNext: false
showAdd: false
```

## Related

* [How to extend the CMS interface](extend_cms_interface)
4 changes: 4 additions & 0 deletions src/Forms/GridField/GridFieldDetailForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,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 Down
146 changes: 146 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,55 @@ protected function getFormActions()
->setUseButtonTag(true)
->addExtraClass('btn-outline-danger btn-hide-outline font-icon-trash-bin action--delete'));
}

if ($gridStateStr = ($this->getRequest()->getVar('gridState')
|| $this->getRequest()->postVar('gridState'))) {
$this->gridField->getState(false)->setValue($gridStateStr);
$this->owner->gridField->getState(false)->setValue($gridStateStr);
}

$actions->push(HiddenField::create('gridState', null, $this->getRequest()->getVar('gridState')));

$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');

$showPrevious = Config::inst()->get("FormActions", "showPrevious");
$showNext = Config::inst()->get("FormActions", "showNext");
$showAdd = Config::inst()->get("FormActions", "showAdd");

if ($showPrevious) {
$previousAndNextGroup->push(FormAction::create('doPrev')
->setUseButtonTag(true)
->setAttribute('data-grid-state', $this->getRequest()->getVar('gridState'))
->setDisabled(!$this->getPreviousRecordID())
->setAttribute('data-text-alternate', 'Previous')
->addExtraClass('btn btn-secondary font-icon-left-open action--previous'));
}

if ($showNext) {
$previousAndNextGroup->push(FormAction::create('doNext')
->setUseButtonTag(true)
->setAttribute('data-grid-state', $this->getRequest()->getVar('gridState'))
->setDisabled(!$this->getNextRecordID())
->setAttribute('data-text-alternate', 'Next')
->addExtraClass('btn btn-secondary font-icon-right-open action--next')
);
}

$rightGroup->push($previousAndNextGroup);


if ($showAdd) {
$rightGroup->push(FormAction::create('doNew')
->setUseButtonTag(true)
->setAttribute('data-grid-state', $this->getRequest()->getVar('gridState'))
->addExtraClass('btn-primary font-icon-plus cms-panel-link rounded'));
}
} 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 +362,12 @@ protected function getFormActions()
$actions->push(new LiteralField('cancelbutton', $text));
}
}

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

// if (isset($previousAndNextGroup)) $actions->push($previousAndNextGroup);
if (isset($rightGroup)) $actions->push($rightGroup);

return $actions;
}

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

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

/**
* Goes to the previous record
* @param array $data The form data
* @param Form $form The Form object
* @return HTTPResponse
*/
public function doPrev($data, $form)
{
Controller::curr()->getResponse()->addHeader("X-Pjax", "Content");
$link = $this->getEditLink($this->getPreviousRecordID());
return Controller::curr()->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 Controller::curr()->redirect($this->owner->Link('addnew'));
}

/**
* 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->owner->gridField->Link(),
"item",
$id,
// todo: use http header instead
'?gridState=' . urlencode($this->owner->gridField->getState(false)->Value())
);
}

/**
* Gets the ID of the previous record in the list.
*
* @return int
*/
public function getPreviousRecordID()
{
$gridField = $this->owner->gridField;
$gridStateStr = $this->getRequest()->postVar('gridState');
$gridField->getState(false)->setValue($gridStateStr);

$map = $gridField->getManipulatedList()->limit(PHP_INT_MAX, 0)->column('ID');
$offset = array_search($this->owner->record->ID, $map);
return isset($map[$offset-1]) ? $map[$offset-1] : false;
}

/**
* Gets the ID of the next record in the list.
*
* @return int
*/
public function getNextRecordID()
{
$gridField = $this->owner->gridField;
$gridStateStr = $this->getRequest()->postVar('gridState');
$gridField->getState(false)->setValue($gridStateStr);

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

/**
* Response object for this request after a successful save
*
Expand Down
8 changes: 7 additions & 1 deletion src/Forms/GridField/GridFieldEditButton.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,13 @@ 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',
// todo: use http header instead
'?gridState=' . urlencode($gridField->getState(false)->Value())
);
}

/**
Expand Down

0 comments on commit 8a8a0dc

Please sign in to comment.