From 332ed6293166f07d81abb0689c1c9333b08acc6c Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Mon, 8 Apr 2019 14:37:36 +0800 Subject: [PATCH 1/8] Increment index count after new item is created Effectively starts the repeater item indexes from 0 --- modules/backend/formwidgets/Repeater.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/modules/backend/formwidgets/Repeater.php b/modules/backend/formwidgets/Repeater.php index d9d6be2cd..f2adcda28 100644 --- a/modules/backend/formwidgets/Repeater.php +++ b/modules/backend/formwidgets/Repeater.php @@ -233,8 +233,8 @@ class Repeater extends FormWidgetBase foreach ($items as $index => $groupCode) { $this->makeItemFormWidget($index, $groupCode); - $this->indexCount = max((int) $index, $this->indexCount); } + $this->indexCount = max(count($items), $this->indexCount); } /** @@ -291,8 +291,6 @@ class Repeater extends FormWidgetBase { self::$onAddItemCalled = true; - $this->indexCount++; - $groupCode = post('_repeater_group'); $this->prepareVars(); @@ -300,7 +298,13 @@ class Repeater extends FormWidgetBase $this->vars['indexValue'] = $this->indexCount; $itemContainer = '@#'.$this->getId('items'); - return [$itemContainer => $this->makePartial('repeater_item')]; + + // Increase index count after item is created + ++$this->indexCount; + + return [ + $itemContainer => $this->makePartial('repeater_item') + ]; } public function onRemoveItem() From 98832fbc5715287a8204b16bc92bb13477447aeb Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Mon, 8 Apr 2019 15:57:04 +0800 Subject: [PATCH 2/8] Initial work on handlers for re-ordering repeater items --- .../repeater/assets/js/repeater.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/backend/formwidgets/repeater/assets/js/repeater.js b/modules/backend/formwidgets/repeater/assets/js/repeater.js index 32d2fdd5e..e3d5cfc0e 100644 --- a/modules/backend/formwidgets/repeater/assets/js/repeater.js +++ b/modules/backend/formwidgets/repeater/assets/js/repeater.js @@ -22,6 +22,9 @@ this.$el = $(element) this.$sortable = $(options.sortableContainer, this.$el) + // Sortable tracking + this.sortingStartIndex = null + $.oc.foundation.controlUtils.markDisposable(element) Base.call(this) this.init() @@ -77,7 +80,9 @@ Repeater.prototype.bindSorting = function() { var sortableOptions = { handle: this.options.sortableHandle, - nested: false + nested: false, + onDragStart: this.proxy(this.onSortStart), + onDrop: this.proxy(this.onSortStop) } this.$sortable.sortable(sortableOptions) @@ -224,6 +229,18 @@ return defaultText } + Repeater.prototype.onSortStart = function($item, container, callback, event) { + this.sortingStartIndex = $item.index() + + callback($item, container, callback, event); + } + + Repeater.prototype.onSortStop = function($item, container, callback, event) { + var endIndex = $item.index() + + callback($item, container, callback, event); + } + // FIELD REPEATER PLUGIN DEFINITION // ============================ From f49b5ab4b812e2ea99c455bcf35adc0b5dc3358e Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Mon, 8 Apr 2019 23:40:41 +0800 Subject: [PATCH 3/8] Add callback for handling sorted repeater items --- modules/backend/formwidgets/Repeater.php | 5 +++++ .../formwidgets/repeater/assets/js/repeater.js | 12 ++++++++++-- .../formwidgets/repeater/partials/_repeater.htm | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/modules/backend/formwidgets/Repeater.php b/modules/backend/formwidgets/Repeater.php index f2adcda28..ffa9a3bed 100644 --- a/modules/backend/formwidgets/Repeater.php +++ b/modules/backend/formwidgets/Repeater.php @@ -322,6 +322,11 @@ class Repeater extends FormWidgetBase return $widget->onRefresh(); } + public function onReorder() + { + // Handle reordering of repeater items + } + // // Group mode // diff --git a/modules/backend/formwidgets/repeater/assets/js/repeater.js b/modules/backend/formwidgets/repeater/assets/js/repeater.js index e3d5cfc0e..c436b220f 100644 --- a/modules/backend/formwidgets/repeater/assets/js/repeater.js +++ b/modules/backend/formwidgets/repeater/assets/js/repeater.js @@ -35,6 +35,7 @@ Repeater.DEFAULTS = { sortableHandle: '.repeater-item-handle', + sortableHandler: null, sortableContainer: 'ul.field-repeater-items', titleFrom: null, minItems: null, @@ -232,13 +233,20 @@ Repeater.prototype.onSortStart = function($item, container, callback, event) { this.sortingStartIndex = $item.index() - callback($item, container, callback, event); + callback($item, container, callback, event) } Repeater.prototype.onSortStop = function($item, container, callback, event) { var endIndex = $item.index() - callback($item, container, callback, event); + this.$el.request(this.options.sortableHandler, { + data: { + _repeater_index: this.sortingStartIndex, + _repeater_new_index: endIndex + } + }) + + callback($item, container, callback, event) } // FIELD REPEATER PLUGIN DEFINITION diff --git a/modules/backend/formwidgets/repeater/partials/_repeater.htm b/modules/backend/formwidgets/repeater/partials/_repeater.htm index 995c42cd8..2647b6ae5 100644 --- a/modules/backend/formwidgets/repeater/partials/_repeater.htm +++ b/modules/backend/formwidgets/repeater/partials/_repeater.htm @@ -3,6 +3,7 @@ + data-sortable-handler="getEventHandler('onReorder') ?>" data-sortable-container="#getId('items') ?>" data-sortable-handle=".getId('items') ?>-handle"> From 744d578df709cdb8ed422db0c28ec8fc1e56ef58 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Tue, 9 Apr 2019 10:52:14 +0800 Subject: [PATCH 4/8] Only run sortable handler if specified --- .../formwidgets/repeater/assets/js/repeater.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/backend/formwidgets/repeater/assets/js/repeater.js b/modules/backend/formwidgets/repeater/assets/js/repeater.js index c436b220f..f5b48ae46 100644 --- a/modules/backend/formwidgets/repeater/assets/js/repeater.js +++ b/modules/backend/formwidgets/repeater/assets/js/repeater.js @@ -239,12 +239,14 @@ Repeater.prototype.onSortStop = function($item, container, callback, event) { var endIndex = $item.index() - this.$el.request(this.options.sortableHandler, { - data: { - _repeater_index: this.sortingStartIndex, - _repeater_new_index: endIndex - } - }) + if (this.options.sortableHandler) { + this.$el.request(this.options.sortableHandler, { + data: { + _repeater_index: this.sortingStartIndex, + _repeater_new_index: endIndex + } + }) + } callback($item, container, callback, event) } From 9b5bd83f10a73e92e5b88a9b9f23230d8bf374eb Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Tue, 9 Apr 2019 15:35:07 +0800 Subject: [PATCH 5/8] Reset indexes when processing POST data --- modules/backend/formwidgets/Repeater.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/modules/backend/formwidgets/Repeater.php b/modules/backend/formwidgets/Repeater.php index ffa9a3bed..af16b9f90 100644 --- a/modules/backend/formwidgets/Repeater.php +++ b/modules/backend/formwidgets/Repeater.php @@ -197,7 +197,7 @@ class Repeater extends FormWidgetBase */ protected function processItems() { - $indexes = $groups = []; + $groups = []; $currentValue = post($this->formField->getName(), $this->getLoadValue()); // Ensure that the minimum number of items are preinitialized @@ -216,25 +216,19 @@ class Repeater extends FormWidgetBase } if (is_array($currentValue)) { - foreach ($currentValue as $index => $value) { - $indexes[] = $index; + foreach ($currentValue as $value) { $groups[] = array_get($value, '_group'); } } - if (!count($indexes)) { + if (!count($groups)) { return; } - $items = array_combine( - (array) $indexes, - (array) ($this->useGroups ? $groups : $indexes) - ); - - foreach ($items as $index => $groupCode) { + foreach ($groups as $index => $groupCode) { $this->makeItemFormWidget($index, $groupCode); } - $this->indexCount = max(count($items), $this->indexCount); + $this->indexCount = max(count($groups), $this->indexCount); } /** From a00e546f5f7419d523ce9db204cf80c8199f3816 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Wed, 10 Apr 2019 13:20:51 +0800 Subject: [PATCH 6/8] Clean up processItems() method --- modules/backend/formwidgets/Repeater.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/backend/formwidgets/Repeater.php b/modules/backend/formwidgets/Repeater.php index af16b9f90..fa69e371d 100644 --- a/modules/backend/formwidgets/Repeater.php +++ b/modules/backend/formwidgets/Repeater.php @@ -197,7 +197,7 @@ class Repeater extends FormWidgetBase */ protected function processItems() { - $groups = []; + $groupMap = []; $currentValue = post($this->formField->getName(), $this->getLoadValue()); // Ensure that the minimum number of items are preinitialized @@ -215,20 +215,20 @@ class Repeater extends FormWidgetBase } } - if (is_array($currentValue)) { + if (is_array($currentValue) && count($currentValue)) { foreach ($currentValue as $value) { - $groups[] = array_get($value, '_group'); + $groupMap[] = array_get($value, '_group'); } } - if (!count($groups)) { + if (!count($groupMap)) { return; } - foreach ($groups as $index => $groupCode) { + foreach ($groupMap as $index => $groupCode) { $this->makeItemFormWidget($index, $groupCode); } - $this->indexCount = max(count($groups), $this->indexCount); + $this->indexCount = max(count($currentValue), $this->indexCount); } /** From ac98f70a2519a67f993e0b9a04fac4eea7877ab0 Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Thu, 11 Apr 2019 10:37:39 +0800 Subject: [PATCH 7/8] Revert reordering handler changes --- modules/backend/formwidgets/Repeater.php | 5 ---- .../repeater/assets/js/repeater.js | 29 +------------------ .../repeater/partials/_repeater.htm | 1 - 3 files changed, 1 insertion(+), 34 deletions(-) diff --git a/modules/backend/formwidgets/Repeater.php b/modules/backend/formwidgets/Repeater.php index fa69e371d..a8b7d7e21 100644 --- a/modules/backend/formwidgets/Repeater.php +++ b/modules/backend/formwidgets/Repeater.php @@ -316,11 +316,6 @@ class Repeater extends FormWidgetBase return $widget->onRefresh(); } - public function onReorder() - { - // Handle reordering of repeater items - } - // // Group mode // diff --git a/modules/backend/formwidgets/repeater/assets/js/repeater.js b/modules/backend/formwidgets/repeater/assets/js/repeater.js index f5b48ae46..32d2fdd5e 100644 --- a/modules/backend/formwidgets/repeater/assets/js/repeater.js +++ b/modules/backend/formwidgets/repeater/assets/js/repeater.js @@ -22,9 +22,6 @@ this.$el = $(element) this.$sortable = $(options.sortableContainer, this.$el) - // Sortable tracking - this.sortingStartIndex = null - $.oc.foundation.controlUtils.markDisposable(element) Base.call(this) this.init() @@ -35,7 +32,6 @@ Repeater.DEFAULTS = { sortableHandle: '.repeater-item-handle', - sortableHandler: null, sortableContainer: 'ul.field-repeater-items', titleFrom: null, minItems: null, @@ -81,9 +77,7 @@ Repeater.prototype.bindSorting = function() { var sortableOptions = { handle: this.options.sortableHandle, - nested: false, - onDragStart: this.proxy(this.onSortStart), - onDrop: this.proxy(this.onSortStop) + nested: false } this.$sortable.sortable(sortableOptions) @@ -230,27 +224,6 @@ return defaultText } - Repeater.prototype.onSortStart = function($item, container, callback, event) { - this.sortingStartIndex = $item.index() - - callback($item, container, callback, event) - } - - Repeater.prototype.onSortStop = function($item, container, callback, event) { - var endIndex = $item.index() - - if (this.options.sortableHandler) { - this.$el.request(this.options.sortableHandler, { - data: { - _repeater_index: this.sortingStartIndex, - _repeater_new_index: endIndex - } - }) - } - - callback($item, container, callback, event) - } - // FIELD REPEATER PLUGIN DEFINITION // ============================ diff --git a/modules/backend/formwidgets/repeater/partials/_repeater.htm b/modules/backend/formwidgets/repeater/partials/_repeater.htm index 2647b6ae5..995c42cd8 100644 --- a/modules/backend/formwidgets/repeater/partials/_repeater.htm +++ b/modules/backend/formwidgets/repeater/partials/_repeater.htm @@ -3,7 +3,6 @@ - data-sortable-handler="getEventHandler('onReorder') ?>" data-sortable-container="#getId('items') ?>" data-sortable-handle=".getId('items') ?>-handle"> From ee2b53fe71fb1e9e5d0a49693362cadb0dcfbedc Mon Sep 17 00:00:00 2001 From: Ben Thomson Date: Thu, 11 Apr 2019 17:57:27 +0800 Subject: [PATCH 8/8] Add hidden "loaded" flag for repeaters This allows the repeater to retrieve the load value from the model only on initialisation. Any further requests to the repeater (ie. AJAX requests) should use the POST data. --- modules/backend/formwidgets/Repeater.php | 30 +++++++++++++++++-- .../repeater/partials/_repeater.htm | 2 ++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/modules/backend/formwidgets/Repeater.php b/modules/backend/formwidgets/Repeater.php index a8b7d7e21..21eef54c0 100644 --- a/modules/backend/formwidgets/Repeater.php +++ b/modules/backend/formwidgets/Repeater.php @@ -77,6 +77,13 @@ class Repeater extends FormWidgetBase protected $groupDefinitions = []; + /** + * Determines if repeater has been initialised previously + * + * @var boolean + */ + protected $loaded = false; + /** * @inheritDoc */ @@ -95,6 +102,11 @@ class Repeater extends FormWidgetBase $this->previewMode = true; } + // Check for loaded flag in POST + if ((bool) post($this->alias . '_loaded') === true) { + $this->loaded = true; + } + $fieldName = $this->formField->getName(false); $this->processGroupMode(); @@ -197,8 +209,17 @@ class Repeater extends FormWidgetBase */ protected function processItems() { + $currentValue = ($this->loaded === true) + ? post($this->formField->getName()) + : $this->getLoadValue(); + + if ($currentValue === null) { + $this->indexCount = 0; + $this->formWidgets = []; + return; + } + $groupMap = []; - $currentValue = post($this->formField->getName(), $this->getLoadValue()); // Ensure that the minimum number of items are preinitialized // ONLY DONE WHEN NOT IN GROUP MODE @@ -269,7 +290,10 @@ class Repeater extends FormWidgetBase */ protected function getValueFromIndex($index) { - $value = post($this->formField->fieldName, $this->getLoadValue()); + $value = ($this->loaded === true) + ? post($this->formField->getName()) + : $this->getLoadValue(); + if (!is_array($value)) { $value = []; } @@ -291,7 +315,7 @@ class Repeater extends FormWidgetBase $this->vars['widget'] = $this->makeItemFormWidget($this->indexCount, $groupCode); $this->vars['indexValue'] = $this->indexCount; - $itemContainer = '@#'.$this->getId('items'); + $itemContainer = '@#' . $this->getId('items'); // Increase index count after item is created ++$this->indexCount; diff --git a/modules/backend/formwidgets/repeater/partials/_repeater.htm b/modules/backend/formwidgets/repeater/partials/_repeater.htm index 995c42cd8..d5198b6de 100644 --- a/modules/backend/formwidgets/repeater/partials/_repeater.htm +++ b/modules/backend/formwidgets/repeater/partials/_repeater.htm @@ -34,6 +34,8 @@ + +