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 @@ + +