Merge pull request #140 from SilbinaryWolf/feature-immediateupdateflag

feat(GridFieldOrderableRows): Re-order gridfield items without immediate reload
This commit is contained in:
Marcus 2016-04-20 13:34:47 +10:00
commit b09519980f
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

@ -253,10 +253,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({