diff --git a/modules/backend/formwidgets/Repeater.php b/modules/backend/formwidgets/Repeater.php
index 3374f40c4..21eef54c0 100644
--- a/modules/backend/formwidgets/Repeater.php
+++ b/modules/backend/formwidgets/Repeater.php
@@ -10,9 +10,6 @@ use October\Rain\Html\Helper as HtmlHelper;
*/
class Repeater extends FormWidgetBase
{
- const INDEX_PREFIX = '___index_';
- const GROUP_PREFIX = '___group_';
-
//
// Configurable properties
//
@@ -56,11 +53,6 @@ class Repeater extends FormWidgetBase
*/
protected $defaultAlias = 'repeater';
- /**
- * @var string Form field name for capturing an index.
- */
- protected $indexInputName;
-
/**
* @var int Count of repeated items.
*/
@@ -83,13 +75,15 @@ class Repeater extends FormWidgetBase
protected $useGroups = false;
- /**
- * @var string Form field name for capturing an index.
- */
- protected $groupInputName;
-
protected $groupDefinitions = [];
+ /**
+ * Determines if repeater has been initialised previously
+ *
+ * @var boolean
+ */
+ protected $loaded = false;
+
/**
* @inheritDoc
*/
@@ -108,14 +102,17 @@ 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->indexInputName = $this->alias.self::INDEX_PREFIX.$fieldName;
- $this->groupInputName = $this->alias.self::GROUP_PREFIX.$fieldName;
$this->processGroupMode();
if (!self::$onAddItemCalled) {
- $this->processExistingItems();
+ $this->processItems();
}
}
@@ -136,7 +133,7 @@ class Repeater extends FormWidgetBase
// Refresh the loaded data to support being modified by filterFields
// @see https://github.com/octobercms/october/issues/2613
if (!self::$onAddItemCalled) {
- $this->processExistingItems();
+ $this->processItems();
}
if ($this->previewMode) {
@@ -145,9 +142,6 @@ class Repeater extends FormWidgetBase
}
}
- $this->vars['indexInputName'] = $this->indexInputName;
- $this->vars['groupInputName'] = $this->groupInputName;
-
$this->vars['prompt'] = $this->prompt;
$this->vars['formWidgets'] = $this->formWidgets;
$this->vars['titleFrom'] = $this->titleFrom;
@@ -186,15 +180,6 @@ class Repeater extends FormWidgetBase
return $value;
}
- if ($this->useGroups) {
- foreach ($value as $index => &$data) {
- $data['_group'] = $this->getGroupCodeFromIndex($index);
- }
- // Make sure the $data reference is removed from memory so that the next loop won't modify it
- // which would cause the last item to receive the group code of the second-last item
- unset($data);
- }
-
if ($this->minItems && count($value) < $this->minItems) {
throw new ApplicationException(Lang::get('backend::lang.repeater.min_items_failed', ['name' => $this->fieldName, 'min' => $this->minItems, 'items' => count($value)]));
}
@@ -219,52 +204,52 @@ class Repeater extends FormWidgetBase
}
/**
- * Processes existing form data and applies it to the form widgets.
+ * Processes form data and applies it to the form widgets.
* @return void
*/
- protected function processExistingItems()
+ protected function processItems()
{
- $loadedIndexes = $loadedGroups = [];
- $loadValue = $this->getLoadValue();
+ $currentValue = ($this->loaded === true)
+ ? post($this->formField->getName())
+ : $this->getLoadValue();
+
+ if ($currentValue === null) {
+ $this->indexCount = 0;
+ $this->formWidgets = [];
+ return;
+ }
+
+ $groupMap = [];
// Ensure that the minimum number of items are preinitialized
// ONLY DONE WHEN NOT IN GROUP MODE
if (!$this->useGroups && $this->minItems > 0) {
- if (!is_array($loadValue)) {
- $loadValue = [];
+ if (!is_array($currentValue)) {
+ $currentValue = [];
for ($i = 0; $i < $this->minItems; $i++) {
- $loadValue[$i] = [];
+ $currentValue[$i] = [];
}
- } elseif (count($loadValue) < $this->minItems) {
- for ($i = 0; $i < ($this->minItems - count($loadValue)); $i++) {
- $loadValue[] = [];
+ } elseif (count($currentValue) < $this->minItems) {
+ for ($i = 0; $i < ($this->minItems - count($currentValue)); $i++) {
+ $currentValue[] = [];
}
}
}
- if (is_array($loadValue)) {
- foreach ($loadValue as $index => $loadedValue) {
- $loadedIndexes[] = $index;
- $loadedGroups[] = array_get($loadedValue, '_group');
+ if (is_array($currentValue) && count($currentValue)) {
+ foreach ($currentValue as $value) {
+ $groupMap[] = array_get($value, '_group');
}
}
- $itemIndexes = post($this->indexInputName, $loadedIndexes);
- $itemGroups = post($this->groupInputName, $loadedGroups);
-
- if (!count($itemIndexes)) {
+ if (!count($groupMap)) {
return;
}
- $items = array_combine(
- (array) $itemIndexes,
- (array) ($this->useGroups ? $itemGroups : $itemIndexes)
- );
-
- foreach ($items as $itemIndex => $groupCode) {
- $this->makeItemFormWidget($itemIndex, $groupCode);
- $this->indexCount = max((int) $itemIndex, $this->indexCount);
+ foreach ($groupMap as $index => $groupCode) {
+ $this->makeItemFormWidget($index, $groupCode);
}
+ $this->indexCount = max(count($currentValue), $this->indexCount);
}
/**
@@ -281,7 +266,7 @@ class Repeater extends FormWidgetBase
$config = $this->makeConfig($configDefinition);
$config->model = $this->model;
- $config->data = $this->getLoadValueFromIndex($index);
+ $config->data = $this->getValueFromIndex($index);
$config->alias = $this->alias . 'Form'.$index;
$config->arrayName = $this->getFieldName().'['.$index.']';
$config->isNested = true;
@@ -300,17 +285,20 @@ class Repeater extends FormWidgetBase
}
/**
- * Returns the load data at a given index.
+ * Returns the data at a given index.
* @param int $index
*/
- protected function getLoadValueFromIndex($index)
+ protected function getValueFromIndex($index)
{
- $loadValue = $this->getLoadValue();
- if (!is_array($loadValue)) {
- $loadValue = [];
+ $value = ($this->loaded === true)
+ ? post($this->formField->getName())
+ : $this->getLoadValue();
+
+ if (!is_array($value)) {
+ $value = [];
}
- return array_get($loadValue, $index, []);
+ return array_get($value, $index, []);
}
//
@@ -321,16 +309,20 @@ class Repeater extends FormWidgetBase
{
self::$onAddItemCalled = true;
- $this->indexCount++;
-
$groupCode = post('_repeater_group');
$this->prepareVars();
$this->vars['widget'] = $this->makeItemFormWidget($this->indexCount, $groupCode);
$this->vars['indexValue'] = $this->indexCount;
- $itemContainer = '@#'.$this->getId('items');
- return [$itemContainer => $this->makePartial('repeater_item')];
+ $itemContainer = '@#' . $this->getId('items');
+
+ // Increase index count after item is created
+ ++$this->indexCount;
+
+ return [
+ $itemContainer => $this->makePartial('repeater_item')
+ ];
}
public function onRemoveItem()
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 @@
+
+