mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge pull request #10439 from creative-commoners/pulls/4/better-button-keep-state
ENH Update page number in the state on reaching the first or the last…
This commit is contained in:
commit
a75317343e
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace SilverStripe\Forms\GridField;
|
namespace SilverStripe\Forms\GridField;
|
||||||
|
|
||||||
|
use LogicException;
|
||||||
use SilverStripe\Admin\LeftAndMain;
|
use SilverStripe\Admin\LeftAndMain;
|
||||||
use SilverStripe\Control\Controller;
|
use SilverStripe\Control\Controller;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
@ -328,7 +329,7 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||||||
/** @var GridFieldDetailForm $component */
|
/** @var GridFieldDetailForm $component */
|
||||||
$component = $this->gridField->getConfig()->getComponentByType(GridFieldDetailForm::class);
|
$component = $this->gridField->getConfig()->getComponentByType(GridFieldDetailForm::class);
|
||||||
$paginator = $this->getGridField()->getConfig()->getComponentByType(GridFieldPaginator::class);
|
$paginator = $this->getGridField()->getConfig()->getComponentByType(GridFieldPaginator::class);
|
||||||
$gridState = $this->getStateManager()->getStateFromRequest($this->gridField, $this->getRequest());
|
$gridState = $this->getGridField()->getState();
|
||||||
if ($component && $paginator && $component->getShowPagination()) {
|
if ($component && $paginator && $component->getShowPagination()) {
|
||||||
$previousIsDisabled = !$this->getPreviousRecordID();
|
$previousIsDisabled = !$this->getPreviousRecordID();
|
||||||
$nextIsDisabled = !$this->getNextRecordID();
|
$nextIsDisabled = !$this->getNextRecordID();
|
||||||
@ -337,8 +338,8 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||||||
LiteralField::create(
|
LiteralField::create(
|
||||||
'previous-record',
|
'previous-record',
|
||||||
HTML::createTag($previousIsDisabled ? 'span' : 'a', [
|
HTML::createTag($previousIsDisabled ? 'span' : 'a', [
|
||||||
'href' => $previousIsDisabled ? '#' : $this->getEditLink($this->getPreviousRecordID()),
|
'href' => $previousIsDisabled ? '#' : $this->getEditLinkForAdjacentRecord(-1),
|
||||||
'data-grid-state' => $gridState,
|
'data-grid-state' => $previousIsDisabled ? $gridState : $this->getGridStateForAdjacentRecord(-1),
|
||||||
'title' => _t(__CLASS__ . '.PREVIOUS', 'Go to previous record'),
|
'title' => _t(__CLASS__ . '.PREVIOUS', 'Go to previous record'),
|
||||||
'aria-label' => _t(__CLASS__ . '.PREVIOUS', 'Go to previous record'),
|
'aria-label' => _t(__CLASS__ . '.PREVIOUS', 'Go to previous record'),
|
||||||
'class' => 'btn btn-secondary font-icon-left-open action--previous discard-confirmation'
|
'class' => 'btn btn-secondary font-icon-left-open action--previous discard-confirmation'
|
||||||
@ -351,8 +352,8 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||||||
LiteralField::create(
|
LiteralField::create(
|
||||||
'next-record',
|
'next-record',
|
||||||
HTML::createTag($nextIsDisabled ? 'span' : 'a', [
|
HTML::createTag($nextIsDisabled ? 'span' : 'a', [
|
||||||
'href' => $nextIsDisabled ? '#' : $this->getEditLink($this->getNextRecordID()),
|
'href' => $nextIsDisabled ? '#' : $this->getEditLinkForAdjacentRecord(+1),
|
||||||
'data-grid-state' => $gridState,
|
'data-grid-state' => $nextIsDisabled ? $gridState : $this->getGridStateForAdjacentRecord(+1),
|
||||||
'title' => _t(__CLASS__ . '.NEXT', 'Go to next record'),
|
'title' => _t(__CLASS__ . '.NEXT', 'Go to next record'),
|
||||||
'aria-label' => _t(__CLASS__ . '.NEXT', 'Go to next record'),
|
'aria-label' => _t(__CLASS__ . '.NEXT', 'Go to next record'),
|
||||||
'class' => 'btn btn-secondary font-icon-right-open action--next discard-confirmation'
|
'class' => 'btn btn-secondary font-icon-right-open action--next discard-confirmation'
|
||||||
@ -413,8 +414,7 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||||||
->addExtraClass('btn-outline-danger btn-hide-outline font-icon-trash-bin action--delete'));
|
->addExtraClass('btn-outline-danger btn-hide-outline font-icon-trash-bin action--delete'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$gridState = $manager->getStateFromRequest($this->gridField, $this->getRequest());
|
$gridState = $this->gridField->getState(false);
|
||||||
$this->gridField->getState(false)->setValue($gridState);
|
|
||||||
$actions->push(HiddenField::create($manager->getStateKey($this->gridField), null, $gridState));
|
$actions->push(HiddenField::create($manager->getStateKey($this->gridField), null, $gridState));
|
||||||
|
|
||||||
$actions->push($this->getRightGroupField());
|
$actions->push($this->getRightGroupField());
|
||||||
@ -561,7 +561,88 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||||||
$id
|
$id
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->getStateManager()->addStateToURL($this->gridField, $link);
|
return $this->gridField->addAllStateToUrl($link);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return array of GridField items on current page plus
|
||||||
|
* first item on the next page and last item on the previous page
|
||||||
|
*/
|
||||||
|
private function getGridFieldItemAdjacencies(): array
|
||||||
|
{
|
||||||
|
$list = $this->getGridField()->getManipulatedList();
|
||||||
|
$paginator = $this->getGridFieldPaginatorState();
|
||||||
|
if (!$paginator) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$currentPage = $paginator->getData('currentPage');
|
||||||
|
$itemsPerPage = $paginator->getData('itemsPerPage');
|
||||||
|
|
||||||
|
$limit = $itemsPerPage + 2;
|
||||||
|
$limitOffset = max(0, $itemsPerPage * ($currentPage-1) -1);
|
||||||
|
|
||||||
|
return $list->limit($limit, $limitOffset)->column('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current paginator state
|
||||||
|
*/
|
||||||
|
private function getGridFieldPaginatorState(): GridState_Data
|
||||||
|
{
|
||||||
|
$state = $this->getGridField()->getState(false);
|
||||||
|
$gridStateStr = $this->getStateManager()->getStateFromRequest($this->gridField, $this->getRequest());
|
||||||
|
if (!empty($gridStateStr)) {
|
||||||
|
$state->setValue($gridStateStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $state->getData()->getData('GridFieldPaginator');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the grid state for an adjacent record
|
||||||
|
*/
|
||||||
|
private function getGridStateForAdjacentRecord(int $offset): GridState_Data
|
||||||
|
{
|
||||||
|
$gridField = $this->getGridField();
|
||||||
|
$map = $this->getGridFieldItemAdjacencies();
|
||||||
|
if (empty($map)) {
|
||||||
|
throw new LogicException('No adjacent records exist');
|
||||||
|
}
|
||||||
|
|
||||||
|
$state = clone $gridField->getState();
|
||||||
|
$index = array_search($this->record->ID, $map);
|
||||||
|
$position = $index + $offset;
|
||||||
|
|
||||||
|
$currentPage = $this->getGridFieldPaginatorState()->getData('currentPage');
|
||||||
|
$itemsPerPage = $this->getGridFieldPaginatorState()->getData('itemsPerPage');
|
||||||
|
$page = $currentPage;
|
||||||
|
$hasMorePages = $this->getNumPages($gridField) > $currentPage;
|
||||||
|
|
||||||
|
if ($position === 0 && $currentPage > 1) {
|
||||||
|
$page = $currentPage - 1;
|
||||||
|
} elseif ($hasMorePages && $position >= $itemsPerPage + 1) {
|
||||||
|
$page = $currentPage + 1;
|
||||||
|
}
|
||||||
|
$state->GridFieldPaginator->currentPage = (int)$page;
|
||||||
|
|
||||||
|
return $state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the edit link for an adjacent record
|
||||||
|
*/
|
||||||
|
private function getEditLinkForAdjacentRecord(int $offset): string
|
||||||
|
{
|
||||||
|
$link = Controller::join_links(
|
||||||
|
$this->gridField->Link(),
|
||||||
|
'item',
|
||||||
|
$this->getAdjacentRecordID($offset)
|
||||||
|
);
|
||||||
|
$state = $this->getGridStateForAdjacentRecord($offset);
|
||||||
|
// Get a dummy gridfield so we can set some future state without affecting the current gridfield
|
||||||
|
$gridField = clone $this->gridField;
|
||||||
|
$gridField->getState(false)->setValue($state);
|
||||||
|
return $gridField->addAllStateToUrl($link);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -570,28 +651,25 @@ class GridFieldDetailForm_ItemRequest extends RequestHandler
|
|||||||
*/
|
*/
|
||||||
private function getAdjacentRecordID($offset)
|
private function getAdjacentRecordID($offset)
|
||||||
{
|
{
|
||||||
$gridField = $this->getGridField();
|
$map = $this->getGridFieldItemAdjacencies();
|
||||||
$list = $gridField->getManipulatedList();
|
if (empty($map)) {
|
||||||
$state = $gridField->getState(false);
|
|
||||||
$gridStateStr = $this->getStateManager()->getStateFromRequest($this->gridField, $this->getRequest());
|
|
||||||
if (!empty($gridStateStr)) {
|
|
||||||
$state->setValue($gridStateStr);
|
|
||||||
}
|
|
||||||
$data = $state->getData();
|
|
||||||
$paginator = $data->getData('GridFieldPaginator');
|
|
||||||
if (!$paginator) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$currentPage = $paginator->getData('currentPage');
|
|
||||||
$itemsPerPage = $paginator->getData('itemsPerPage');
|
|
||||||
|
|
||||||
$limit = $itemsPerPage + 2;
|
|
||||||
$limitOffset = max(0, $itemsPerPage * ($currentPage-1) -1);
|
|
||||||
|
|
||||||
$map = $list->limit($limit, $limitOffset)->column('ID');
|
|
||||||
$index = array_search($this->record->ID, $map ?? []);
|
$index = array_search($this->record->ID, $map ?? []);
|
||||||
return isset($map[$index+$offset]) ? $map[$index+$offset] : false;
|
$position = $index + $offset;
|
||||||
|
return isset($map[$position]) ? $map[$position] : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of GridField pages
|
||||||
|
*/
|
||||||
|
private function getNumPages(GridField $gridField): int
|
||||||
|
{
|
||||||
|
return $gridField
|
||||||
|
->getConfig()
|
||||||
|
->getComponentByType(GridFieldPaginator::class)
|
||||||
|
->getTemplateParameters($gridField)
|
||||||
|
->toMap()['NumPages'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +40,11 @@ class GridState_Data
|
|||||||
return $this->getData($name, $default);
|
return $this->getData($name, $default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function __clone()
|
||||||
|
{
|
||||||
|
$this->data = $this->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise the defaults values for the grid field state
|
* Initialise the defaults values for the grid field state
|
||||||
* These values won't be included in getChangesArray()
|
* These values won't be included in getChangesArray()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user