Remove extra __index_ and __group_ fields from the Repeater and use only the data itself to handle initializing widgets and processing data.

Refs: #4230
This commit is contained in:
Luke Towers 2019-04-04 01:23:32 -06:00
parent 49f3cd632e
commit b4b4b1b566
2 changed files with 29 additions and 64 deletions

View File

@ -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,11 +75,6 @@ class Repeater extends FormWidgetBase
protected $useGroups = false;
/**
* @var string Form field name for capturing an index.
*/
protected $groupInputName;
protected $groupDefinitions = [];
/**
@ -109,13 +96,11 @@ class Repeater extends FormWidgetBase
}
$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 +121,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 +130,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 +168,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,51 +192,48 @@ 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();
$indexes = $groups = [];
$currentValue = post($this->formField->fieldName, $this->getLoadValue());
// 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)) {
foreach ($currentValue as $index => $value) {
$indexes[] = $index;
$groups[] = array_get($value, '_group');
}
}
$itemIndexes = post($this->indexInputName, $loadedIndexes);
$itemGroups = post($this->groupInputName, $loadedGroups);
if (!count($itemIndexes)) {
if (!count($indexes)) {
return;
}
$items = array_combine(
(array) $itemIndexes,
(array) ($this->useGroups ? $itemGroups : $itemIndexes)
(array) $indexes,
(array) ($this->useGroups ? $groups : $indexes)
);
foreach ($items as $itemIndex => $groupCode) {
$this->makeItemFormWidget($itemIndex, $groupCode);
$this->indexCount = max((int) $itemIndex, $this->indexCount);
foreach ($items as $index => $groupCode) {
$this->makeItemFormWidget($index, $groupCode);
$this->indexCount = max((int) $index, $this->indexCount);
}
}
@ -281,7 +251,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 +270,17 @@ 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 = post($this->formField->fieldName, $this->getLoadValue());
if (!is_array($value)) {
$value = [];
}
return array_get($loadValue, $index, []);
return array_get($value, $index, []);
}
//

View File

@ -45,9 +45,4 @@
<?php endif ?>
</div>
<input type="hidden" name="<?= $indexInputName ?>[]" value="<?= $indexValue ?>" />
<?php if ($useGroups): ?>
<input type="hidden" name="<?= $groupInputName ?>[]" value="<?= $groupCode ?>" />
<?php endif ?>
</li>