feat(GridFieldOrderableRows): Added the ability to change setting on GridFieldOrderableRows so that instead of updating the order immediately, it updates when you hit 'Save Draft' or 'Save and Publish'.

This commit is contained in:
Jake Bentvelzen 2016-04-10 18:48:21 +10:00
parent 84cf612582
commit 1e3d51730f
2 changed files with 134 additions and 54 deletions

View File

@ -10,7 +10,14 @@ class GridFieldOrderableRows extends RequestHandler implements
GridField_ColumnProvider,
GridField_DataManipulator,
GridField_HTMLProvider,
GridField_URLHandler {
GridField_URLHandler,
GridField_SaveHandler {
/**
* @see $immediateUpdate
* @var boolean
*/
private static $default_immediate_update = true;
private static $allowed_actions = array(
'handleReorder',
@ -25,6 +32,15 @@ class GridFieldOrderableRows extends RequestHandler implements
*/
protected $sortField;
/**
* If set to true, when an item is re-ordered, it will update on the
* database and refresh the gridfield. When set to false, it will only
* update the sort order when the record is saved.
*
* @var boolean
*/
protected $immediateUpdate;
/**
* Extra sort fields to apply before the sort field.
*
@ -47,6 +63,7 @@ class GridFieldOrderableRows extends RequestHandler implements
public function __construct($sortField = 'Sort') {
parent::__construct();
$this->sortField = $sortField;
$this->immediateUpdate = $this->config()->default_immediate_update;
}
/**
@ -67,6 +84,23 @@ class GridFieldOrderableRows extends RequestHandler implements
return $this;
}
/**
* @return boolean
*/
public function getImmediateUpdate() {
return $this->immediateUpdate;
}
/**
* @see $immediateUpdate
* @param boolean $immediateUpdate
* @return GridFieldOrderableRows $this
*/
public function setImmediateUpdate($bool) {
$this->immediateUpdate = $bool;
return $this;
}
/**
* @return string|array
*/
@ -146,6 +180,7 @@ class GridFieldOrderableRows extends RequestHandler implements
GridFieldExtensions::include_requirements();
$field->addExtraClass('ss-gridfield-orderable');
$field->setAttribute('data-immediate-update', (string)(int)$this->immediateUpdate);
$field->setAttribute('data-url-reorder', $field->Link('reorder'));
$field->setAttribute('data-url-movetopage', $field->Link('movetopage'));
}
@ -206,6 +241,10 @@ class GridFieldOrderableRows extends RequestHandler implements
* @return SS_HTTPResponse
*/
public function handleReorder($grid, $request) {
if (!$this->immediateUpdate)
{
$this->httpError(400);
}
$list = $grid->getList();
$modelClass = $grid->getModelClass();
if ($list instanceof ManyManyList && !singleton($modelClass)->canView()) {
@ -214,63 +253,17 @@ class GridFieldOrderableRows extends RequestHandler implements
$this->httpError(403);
}
$ids = $request->postVar('order');
$field = $this->getSortField();
if(!is_array($ids)) {
$this->httpError(400);
}
$sortterm = '';
if ($this->extraSortFields) {
if (is_array($this->extraSortFields)) {
foreach($this->extraSortFields as $col => $dir) {
$sortterm .= "$col $dir, ";
}
} else {
$sortterm = $this->extraSortFields.', ';
}
}
$sortterm .= '"'.$this->getSortTable($list).'"."'.$field.'"';
$items = $list->filter('ID', $ids)->sort($sortterm);
// Ensure that each provided ID corresponded to an actual object.
if(count($items) != count($ids)) {
$this->httpError(404);
}
// Save any un-comitted changes to the gridfield
if(($form = $grid->getForm()) && ($record = $form->getRecord()) ) {
$form->loadDataFrom($request->requestVars(), true);
$grid->saveInto($record);
}
// Populate each object we are sorting with a sort value.
$this->populateSortValues($items);
// Generate the current sort values.
if ($items instanceof ManyManyList)
$ids = $request->postVar('order');
if (!$this->executeReorder($grid, $ids))
{
$current = array();
foreach ($items->toArray() as $record)
{
// NOTE: _SortColumn0 is the first ->sort() field
// used by SS when functions are detected in a SELECT
// or CASE WHEN.
if (isset($record->_SortColumn0)) {
$current[$record->ID] = $record->_SortColumn0;
} else {
$current[$record->ID] = $record->$field;
}
}
$this->httpError(400);
}
else
{
$current = $items->map('ID', $field)->toArray();
}
// Perform the actual re-ordering.
$this->reorderItems($list, $current, $ids);
return $grid->FieldHolder();
}
@ -334,6 +327,82 @@ class GridFieldOrderableRows extends RequestHandler implements
return $grid->FieldHolder();
}
/**
* Handle saving when 'immediateUpdate' is disabled, otherwise this isn't
* necessary for the default sort mode.
*/
public function handleSave(GridField $grid, DataObjectInterface $record) {
if (!$this->immediateUpdate)
{
$list = $grid->getList();
$value = $grid->Value();
if (isset($value['GridFieldEditableColumns']) && $value['GridFieldEditableColumns'])
{
$rows = $value['GridFieldEditableColumns'];
$ids = array();
foreach ($rows as $id => $data)
{
$ids[] = $id;
}
$this->executeReorder($grid, $ids);
}
}
}
protected function executeReorder(GridField $grid, $ids) {
if(!is_array($ids)) {
return false;
}
$field = $this->getSortField();
$sortterm = '';
if ($this->extraSortFields) {
if (is_array($this->extraSortFields)) {
foreach($this->extraSortFields as $col => $dir) {
$sortterm .= "$col $dir, ";
}
} else {
$sortterm = $this->extraSortFields.', ';
}
}
$list = $grid->getList();
$sortterm .= '"'.$this->getSortTable($list).'"."'.$field.'"';
$items = $list->filter('ID', $ids)->sort($sortterm);
// Ensure that each provided ID corresponded to an actual object.
if(count($items) != count($ids)) {
return false;
}
// Populate each object we are sorting with a sort value.
$this->populateSortValues($items);
// Generate the current sort values.
if ($items instanceof ManyManyList)
{
$current = array();
foreach ($items->toArray() as $record)
{
// NOTE: _SortColumn0 is the first ->sort() field
// used by SS when functions are detected in a SELECT
// or CASE WHEN.
if (isset($record->_SortColumn0)) {
$current[$record->ID] = $record->_SortColumn0;
} else {
$current[$record->ID] = $record->$field;
}
}
}
else
{
$current = $items->map('ID', $field)->toArray();
}
// Perform the actual re-ordering.
$this->reorderItems($list, $current, $ids);
return true;
}
protected function reorderItems($list, array $values, array $order) {
// Get a list of sort values that can be used.
$pool = array_values($values);

View File

@ -198,10 +198,21 @@
return { name: "order[]", value: $(this).data("id") };
});
grid.reload({
url: grid.data("url-reorder"),
data: data.get()
});
if (grid.data("immediate-update"))
{
grid.reload({
url: grid.data("url-reorder"),
data: data.get()
});
}
else
{
// Tells the user they have unsaved changes when they
// try and leave the page after sorting, also updates the
// save buttons to show the user they've made a change.
var form = $('.cms-edit-form');
form.addClass('changed');
}
};
this.sortable({