mirror of
https://github.com/symbiote/silverstripe-gridfieldextensions.git
synced 2024-10-22 17:05:39 +02:00
Merge pull request #140 from SilbinaryWolf/feature-immediateupdateflag
feat(GridFieldOrderableRows): Re-order gridfield items without immediate reload
This commit is contained in:
commit
b09519980f
@ -10,7 +10,14 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
GridField_ColumnProvider,
|
GridField_ColumnProvider,
|
||||||
GridField_DataManipulator,
|
GridField_DataManipulator,
|
||||||
GridField_HTMLProvider,
|
GridField_HTMLProvider,
|
||||||
GridField_URLHandler {
|
GridField_URLHandler,
|
||||||
|
GridField_SaveHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see $immediateUpdate
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
private static $default_immediate_update = true;
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'handleReorder',
|
'handleReorder',
|
||||||
@ -25,6 +32,15 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
*/
|
*/
|
||||||
protected $sortField;
|
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.
|
* Extra sort fields to apply before the sort field.
|
||||||
*
|
*
|
||||||
@ -47,6 +63,7 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
public function __construct($sortField = 'Sort') {
|
public function __construct($sortField = 'Sort') {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
$this->sortField = $sortField;
|
$this->sortField = $sortField;
|
||||||
|
$this->immediateUpdate = $this->config()->default_immediate_update;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,6 +84,23 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
return $this;
|
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
|
* @return string|array
|
||||||
*/
|
*/
|
||||||
@ -146,6 +180,7 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
GridFieldExtensions::include_requirements();
|
GridFieldExtensions::include_requirements();
|
||||||
|
|
||||||
$field->addExtraClass('ss-gridfield-orderable');
|
$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-reorder', $field->Link('reorder'));
|
||||||
$field->setAttribute('data-url-movetopage', $field->Link('movetopage'));
|
$field->setAttribute('data-url-movetopage', $field->Link('movetopage'));
|
||||||
}
|
}
|
||||||
@ -206,6 +241,10 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
* @return SS_HTTPResponse
|
* @return SS_HTTPResponse
|
||||||
*/
|
*/
|
||||||
public function handleReorder($grid, $request) {
|
public function handleReorder($grid, $request) {
|
||||||
|
if (!$this->immediateUpdate)
|
||||||
|
{
|
||||||
|
$this->httpError(400);
|
||||||
|
}
|
||||||
$list = $grid->getList();
|
$list = $grid->getList();
|
||||||
$modelClass = $grid->getModelClass();
|
$modelClass = $grid->getModelClass();
|
||||||
if ($list instanceof ManyManyList && !singleton($modelClass)->canView()) {
|
if ($list instanceof ManyManyList && !singleton($modelClass)->canView()) {
|
||||||
@ -214,63 +253,17 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
$this->httpError(403);
|
$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
|
// Save any un-comitted changes to the gridfield
|
||||||
if(($form = $grid->getForm()) && ($record = $form->getRecord()) ) {
|
if(($form = $grid->getForm()) && ($record = $form->getRecord()) ) {
|
||||||
$form->loadDataFrom($request->requestVars(), true);
|
$form->loadDataFrom($request->requestVars(), true);
|
||||||
$grid->saveInto($record);
|
$grid->saveInto($record);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate each object we are sorting with a sort value.
|
$ids = $request->postVar('order');
|
||||||
$this->populateSortValues($items);
|
if (!$this->executeReorder($grid, $ids))
|
||||||
|
|
||||||
// Generate the current sort values.
|
|
||||||
if ($items instanceof ManyManyList)
|
|
||||||
{
|
{
|
||||||
$current = array();
|
$this->httpError(400);
|
||||||
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 $grid->FieldHolder();
|
return $grid->FieldHolder();
|
||||||
}
|
}
|
||||||
@ -334,6 +327,82 @@ class GridFieldOrderableRows extends RequestHandler implements
|
|||||||
return $grid->FieldHolder();
|
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) {
|
protected function reorderItems($list, array $values, array $order) {
|
||||||
// Get a list of sort values that can be used.
|
// Get a list of sort values that can be used.
|
||||||
$pool = array_values($values);
|
$pool = array_values($values);
|
||||||
|
@ -253,10 +253,21 @@
|
|||||||
return { name: "order[]", value: $(this).data("id") };
|
return { name: "order[]", value: $(this).data("id") };
|
||||||
});
|
});
|
||||||
|
|
||||||
grid.reload({
|
if (grid.data("immediate-update"))
|
||||||
url: grid.data("url-reorder"),
|
{
|
||||||
data: data.get()
|
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({
|
this.sortable({
|
||||||
|
Loading…
Reference in New Issue
Block a user