Implemented minItems repeater property on client & server
Also implemented maxItems on server (previously only client). Fixes https://github.com/octobercms/october/issues/3668
This commit is contained in:
parent
6774920003
commit
cbed54a263
|
|
@ -1,8 +1,9 @@
|
||||||
<?php namespace Backend\FormWidgets;
|
<?php namespace Backend\FormWidgets;
|
||||||
|
|
||||||
|
use Lang;
|
||||||
|
use ApplicationException;
|
||||||
use Backend\Classes\FormField;
|
use Backend\Classes\FormField;
|
||||||
use Backend\Classes\FormWidgetBase;
|
use Backend\Classes\FormWidgetBase;
|
||||||
use ApplicationException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repeater Form Widget
|
* Repeater Form Widget
|
||||||
|
|
@ -37,7 +38,12 @@ class Repeater extends FormWidgetBase
|
||||||
public $titleFrom = false;
|
public $titleFrom = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var int Maximum repeated items allowable.
|
* @var int Minimum items required. Pre-displays those items when not using groups
|
||||||
|
*/
|
||||||
|
public $minItems = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int Maximum items permitted
|
||||||
*/
|
*/
|
||||||
public $maxItems = null;
|
public $maxItems = null;
|
||||||
|
|
||||||
|
|
@ -94,6 +100,7 @@ class Repeater extends FormWidgetBase
|
||||||
'prompt',
|
'prompt',
|
||||||
'sortable',
|
'sortable',
|
||||||
'titleFrom',
|
'titleFrom',
|
||||||
|
'minItems',
|
||||||
'maxItems',
|
'maxItems',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -144,6 +151,7 @@ class Repeater extends FormWidgetBase
|
||||||
$this->vars['prompt'] = $this->prompt;
|
$this->vars['prompt'] = $this->prompt;
|
||||||
$this->vars['formWidgets'] = $this->formWidgets;
|
$this->vars['formWidgets'] = $this->formWidgets;
|
||||||
$this->vars['titleFrom'] = $this->titleFrom;
|
$this->vars['titleFrom'] = $this->titleFrom;
|
||||||
|
$this->vars['minItems'] = $this->minItems;
|
||||||
$this->vars['maxItems'] = $this->maxItems;
|
$this->vars['maxItems'] = $this->maxItems;
|
||||||
|
|
||||||
$this->vars['useGroups'] = $this->useGroups;
|
$this->vars['useGroups'] = $this->useGroups;
|
||||||
|
|
@ -184,6 +192,13 @@ class Repeater extends FormWidgetBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)]));
|
||||||
|
}
|
||||||
|
if ($this->maxItems && count($value) > $this->maxItems) {
|
||||||
|
throw new ApplicationException(Lang::get('backend::lang.repeater.max_items_failed', ['name' => $this->fieldName, 'max' => $this->maxItems, 'items' => count($value)]));
|
||||||
|
}
|
||||||
|
|
||||||
return array_values($value);
|
return array_values($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,6 +211,21 @@ class Repeater extends FormWidgetBase
|
||||||
$loadedIndexes = $loadedGroups = [];
|
$loadedIndexes = $loadedGroups = [];
|
||||||
$loadValue = $this->getLoadValue();
|
$loadValue = $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 = [];
|
||||||
|
for ($i = 0; $i < $this->minItems; $i++) {
|
||||||
|
$loadValue[$i] = [];
|
||||||
|
}
|
||||||
|
} elseif (count($loadValue) < $this->minItems) {
|
||||||
|
for ($i = 0; $i < ($this->minItems - count($loadValue)); $i++) {
|
||||||
|
$loadValue[] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (is_array($loadValue)) {
|
if (is_array($loadValue)) {
|
||||||
foreach ($loadValue as $index => $loadedValue) {
|
foreach ($loadValue as $index => $loadedValue) {
|
||||||
$loadedIndexes[] = $index;
|
$loadedIndexes[] = $index;
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
sortableHandle: '.repeater-item-handle',
|
sortableHandle: '.repeater-item-handle',
|
||||||
sortableContainer: 'ul.field-repeater-items',
|
sortableContainer: 'ul.field-repeater-items',
|
||||||
titleFrom: null,
|
titleFrom: null,
|
||||||
|
minItems: null,
|
||||||
maxItems: null
|
maxItems: null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,6 +123,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater.prototype.togglePrompt = function () {
|
Repeater.prototype.togglePrompt = function () {
|
||||||
|
if (this.options.minItems && this.options.minItems > 0) {
|
||||||
|
var repeatedItems = this.$el.find('> .field-repeater-items > .field-repeater-item').length,
|
||||||
|
$removeItemBtn = this.$el.find('> .field-repeater-items > .field-repeater-item > .repeater-item-remove')
|
||||||
|
|
||||||
|
$removeItemBtn.toggle(repeatedItems > this.options.minItems)
|
||||||
|
}
|
||||||
|
|
||||||
if (this.options.maxItems && this.options.maxItems > 0) {
|
if (this.options.maxItems && this.options.maxItems > 0) {
|
||||||
var repeatedItems = this.$el.find('> .field-repeater-items > .field-repeater-item').length,
|
var repeatedItems = this.$el.find('> .field-repeater-items > .field-repeater-item').length,
|
||||||
$addItemBtn = this.$el.find('> .field-repeater-add-item')
|
$addItemBtn = this.$el.find('> .field-repeater-add-item')
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<div class="field-repeater"
|
<div class="field-repeater"
|
||||||
data-control="fieldrepeater"
|
data-control="fieldrepeater"
|
||||||
<?= $titleFrom ? 'data-title-from="'.$titleFrom.'"' : '' ?>
|
<?= $titleFrom ? 'data-title-from="'.$titleFrom.'"' : '' ?>
|
||||||
|
<?= $minItems ? 'data-min-items="'.$minItems.'"' : '' ?>
|
||||||
<?= $maxItems ? 'data-max-items="'.$maxItems.'"' : '' ?>
|
<?= $maxItems ? 'data-max-items="'.$maxItems.'"' : '' ?>
|
||||||
data-sortable-container="#<?= $this->getId('items') ?>"
|
data-sortable-container="#<?= $this->getId('items') ?>"
|
||||||
data-sortable-handle=".<?= $this->getId('items') ?>-handle">
|
data-sortable-handle=".<?= $this->getId('items') ?>-handle">
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,10 @@ return [
|
||||||
'remove_confirm' => 'Are you sure?',
|
'remove_confirm' => 'Are you sure?',
|
||||||
'remove_file' => 'Remove file'
|
'remove_file' => 'Remove file'
|
||||||
],
|
],
|
||||||
|
'repeater' => [
|
||||||
|
'min_items_failed' => ':name requires a minimum of :min items, only :items were provided',
|
||||||
|
'max_items_failed' => ':name only allows up to :max items, :items were provided',
|
||||||
|
],
|
||||||
'form' => [
|
'form' => [
|
||||||
'create_title' => 'New :name',
|
'create_title' => 'New :name',
|
||||||
'update_title' => 'Edit :name',
|
'update_title' => 'Edit :name',
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue