diff --git a/javascript/GridFieldExtensions.js b/javascript/GridFieldExtensions.js
index d961716..1381f10 100644
--- a/javascript/GridFieldExtensions.js
+++ b/javascript/GridFieldExtensions.js
@@ -264,6 +264,82 @@
*/
$(".ss-gridfield-orderable tbody").entwine({
+ // reload the gridfield without triggering the change event
+ // this is because the change has already been saved by reorder action
+ reload: function (ajaxOpts, successCallback) {
+ var self = this.getGridField(), form = this.closest('form'),
+ focusedElName = this.find(':input:focus').attr('name'), // Save focused element for restoring after refresh
+ data = form.find(':input').serializeArray();
+
+ if (!ajaxOpts) {
+ ajaxOpts = {};
+ }
+ if (!ajaxOpts.data) {
+ ajaxOpts.data = [];
+ }
+ ajaxOpts.data = ajaxOpts.data.concat(data);
+
+ // Include any GET parameters from the current URL, as the view state might depend on it.
+ // For example, a list prefiltered through external search criteria might be passed to GridField.
+ if (window.location.search) {
+ ajaxOpts.data = window.location.search.replace(/^\?/, '') + '&' + $.param(ajaxOpts.data);
+ }
+
+ form.addClass('loading');
+
+ $.ajax($.extend({}, {
+ headers: {"X-Pjax": 'CurrentField'},
+ type: "POST",
+ url: this.data('url'),
+ dataType: 'html',
+ success: function (data) {
+ // Replace the grid field with response, not the form.
+ // TODO Only replaces all its children, to avoid replacing the current scope
+ // of the executing method. Means that it doesn't retrigger the onmatch() on the main container.
+ self.empty().append($(data).children());
+
+ // Refocus previously focused element. Useful e.g. for finding+adding
+ // multiple relationships via keyboard.
+ if (focusedElName) self.find(':input[name="' + focusedElName + '"]').focus();
+
+ // Update filter
+ if (self.find('.grid-field__filter-header').length) {
+ var content;
+ if (ajaxOpts.data[0].filter == "show") {
+ content = '';
+ self.addClass('show-filter').find('.grid-field__filter-header').show();
+ } else {
+ content = '';
+ self.removeClass('show-filter').find('.grid-field__filter-header').hide();
+ }
+
+ self.find('.sortable-header th:last').html(content);
+ }
+
+ form.removeClass('loading');
+ if (successCallback) {
+ successCallback.apply(this, arguments);
+ }
+ self.trigger('reload', self);
+
+ // update publish button if necessary
+ const publish = $('#Form_EditForm_action_publish');
+
+ // button needs to be updated only if it's in published state
+ if (publish.length > 0 && publish.hasClass('btn-outline-primary')) {
+ publish.removeClass('btn-outline-primary');
+ publish.removeClass('font-icon-tick');
+ publish.addClass('btn-primary');
+ publish.addClass('font-icon-rocket');
+ publish.find('.btn__title').html('Save & publish');
+ }
+ },
+ error: function (e) {
+ alert(i18n._t('Admin.ERRORINTRANSACTION'));
+ form.removeClass('loading');
+ }
+ }, ajaxOpts));
+ },
rebuildSort: function() {
var grid = this.getGridField();
@@ -320,7 +396,7 @@
var grid = self.getGridField();
if (grid.data("immediate-update") && postback)
{
- grid.reload({
+ self.reload({
url: grid.data("url-reorder")
});
}
diff --git a/src/GridFieldOrderableRows.php b/src/GridFieldOrderableRows.php
index 91cb6d3..8b9a314 100755
--- a/src/GridFieldOrderableRows.php
+++ b/src/GridFieldOrderableRows.php
@@ -20,6 +20,7 @@ use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\ManyManyList;
use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\SS_Map;
+use SilverStripe\Versioned\Versioned;
use SilverStripe\View\ViewableData;
use Exception;
@@ -171,6 +172,35 @@ class GridFieldOrderableRows extends RequestHandler implements
return $this;
}
+ /**
+ * Validates sortable list
+ *
+ * @param SS_List $list
+ * @throws Exception
+ */
+ public function validateSortField(SS_List $list)
+ {
+ $field = $this->getSortField();
+
+ if ($list instanceof ManyManyList) {
+ $extra = $list->getExtraFields();
+
+ if ($extra && array_key_exists($field, $extra)) {
+ return;
+ }
+ }
+
+ $classes = ClassInfo::dataClassesFor($list->dataClass());
+
+ foreach ($classes as $class) {
+ if (singleton($class)->hasDataBaseField($field)) {
+ return;
+ }
+ }
+
+ throw new \Exception("Couldn't find the sort field '" . $field . "'");
+ }
+
/**
* Gets the table which contains the sort field.
*
@@ -504,11 +534,9 @@ class GridFieldOrderableRows extends RequestHandler implements
}
// If not a ManyManyList and using versioning, detect it.
- $isVersioned = false;
+ $this->validateSortField($list);
$class = $list->dataClass();
- if ($class == $this->getSortTable($list)) {
- $isVersioned = $class::has_extension('SilverStripe\\ORM\\Versioning\\Versioned');
- }
+ $isVersioned = $class::has_extension(Versioned::class);
// Loop through each item, and update the sort values which do not
// match to order the objects.