Merge pull request #4234 from octobercms/fix/repeater-cleanup
Simplify Repeater Logic. Fixes #4230. Related: https://github.com/rainlab/translate-plugin/pull/466
This commit is contained in:
commit
f3f655cc25
|
|
@ -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,8 +309,6 @@ class Repeater extends FormWidgetBase
|
|||
{
|
||||
self::$onAddItemCalled = true;
|
||||
|
||||
$this->indexCount++;
|
||||
|
||||
$groupCode = post('_repeater_group');
|
||||
|
||||
$this->prepareVars();
|
||||
|
|
@ -330,7 +316,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()
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
</a>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="<?= $this->alias; ?>_loaded" value="1">
|
||||
<?php endif ?>
|
||||
|
||||
<script type="text/template" data-group-palette-template>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue