mirror of
https://github.com/wintercms/winter.git
synced 2024-06-28 05:33:29 +02:00
Merge pull request #2723 from octobercms/feature-RepeaterMaxItems
Add support for maxItems to the Repeater FormWidget. Thanks to @panakour for the initial work in #2710. Fixes #1710, #2649
This commit is contained in:
commit
fedf7b2b7d
@ -48,11 +48,16 @@ class Repeater extends FormWidgetBase
|
|||||||
*/
|
*/
|
||||||
protected $formWidgets = [];
|
protected $formWidgets = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool Stops nested repeaters populating from previous sibling.
|
* @var bool Stops nested repeaters populating from previous sibling.
|
||||||
*/
|
*/
|
||||||
protected static $onAddItemCalled = false;
|
protected static $onAddItemCalled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int Maximum repeated items (0 == unlimited items)
|
||||||
|
*/
|
||||||
|
protected $maxItems = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@ -62,6 +67,7 @@ class Repeater extends FormWidgetBase
|
|||||||
'form',
|
'form',
|
||||||
'prompt',
|
'prompt',
|
||||||
'sortable',
|
'sortable',
|
||||||
|
'maxItems',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (!self::$onAddItemCalled) {
|
if (!self::$onAddItemCalled) {
|
||||||
@ -86,6 +92,7 @@ class Repeater extends FormWidgetBase
|
|||||||
$this->vars['indexName'] = self::INDEX_PREFIX.$this->formField->getName(false).'[]';
|
$this->vars['indexName'] = self::INDEX_PREFIX.$this->formField->getName(false).'[]';
|
||||||
$this->vars['prompt'] = $this->prompt;
|
$this->vars['prompt'] = $this->prompt;
|
||||||
$this->vars['formWidgets'] = $this->formWidgets;
|
$this->vars['formWidgets'] = $this->formWidgets;
|
||||||
|
$this->vars['maxItems'] = $this->maxItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,25 +33,28 @@
|
|||||||
Repeater.DEFAULTS = {
|
Repeater.DEFAULTS = {
|
||||||
sortableHandle: '.repeater-item-handle',
|
sortableHandle: '.repeater-item-handle',
|
||||||
sortableContainer: 'ul.field-repeater-items',
|
sortableContainer: 'ul.field-repeater-items',
|
||||||
titleFrom: null
|
titleFrom: null,
|
||||||
|
maxItems: null
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater.prototype.init = function() {
|
Repeater.prototype.init = function() {
|
||||||
this.bindSorting()
|
this.bindSorting()
|
||||||
|
|
||||||
this.$el.on('ajaxDone', '[data-repeater-remove]', this.proxy(this.onRemoveItemSuccess))
|
this.$el.on('ajaxDone', '> .field-repeater-items > .field-repeater-item > .repeater-item-remove > [data-repeater-remove]', this.proxy(this.onRemoveItemSuccess))
|
||||||
this.$el.on('ajaxDone', '[data-repeater-add]', this.proxy(this.onAddItemSuccess))
|
this.$el.on('ajaxDone', '> .field-repeater-add-item > [data-repeater-add]', this.proxy(this.onAddItemSuccess))
|
||||||
this.$el.on('click', '> ul > li > .repeater-item-collapse .repeater-item-collapse-one', this.proxy(this.toggleCollapse))
|
this.$el.on('click', '> ul > li > .repeater-item-collapse .repeater-item-collapse-one', this.proxy(this.toggleCollapse))
|
||||||
|
|
||||||
this.$el.one('dispose-control', this.proxy(this.dispose))
|
this.$el.one('dispose-control', this.proxy(this.dispose))
|
||||||
|
|
||||||
|
this.togglePrompt()
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater.prototype.dispose = function() {
|
Repeater.prototype.dispose = function() {
|
||||||
this.$sortable.sortable('destroy')
|
this.$sortable.sortable('destroy')
|
||||||
|
|
||||||
this.$el.off('ajaxDone', '[data-repeater-remove]', this.proxy(this.onRemoveItemSuccess))
|
this.$el.off('ajaxDone', '> .field-repeater-items > .field-repeater-item > .repeater-item-remove > [data-repeater-remove]', this.proxy(this.onRemoveItemSuccess))
|
||||||
this.$el.off('ajaxDone', '[data-repeater-add]', this.proxy(this.onAddItemSuccess))
|
this.$el.off('ajaxDone', '> .field-repeater-add-item > [data-repeater-add]', this.proxy(this.onAddItemSuccess))
|
||||||
this.$el.off('click', '> ul > li > .repeater-item-collapse .repeater-item-collapse-one', this.proxy(this.toggleCollapse))
|
this.$el.off('click', '> .field-repeater-items > .field-repeater-item > .repeater-item-collapse .repeater-item-collapse-one', this.proxy(this.toggleCollapse))
|
||||||
|
|
||||||
this.$el.off('dispose-control', this.proxy(this.dispose))
|
this.$el.off('dispose-control', this.proxy(this.dispose))
|
||||||
this.$el.removeData('oc.repeater')
|
this.$el.removeData('oc.repeater')
|
||||||
@ -79,10 +82,24 @@
|
|||||||
|
|
||||||
Repeater.prototype.onRemoveItemSuccess = function(ev) {
|
Repeater.prototype.onRemoveItemSuccess = function(ev) {
|
||||||
$(ev.target).closest('.field-repeater-item').remove()
|
$(ev.target).closest('.field-repeater-item').remove()
|
||||||
|
this.togglePrompt()
|
||||||
}
|
}
|
||||||
|
|
||||||
// This fires twice, not sure why
|
|
||||||
Repeater.prototype.onAddItemSuccess = function(ev) {
|
Repeater.prototype.onAddItemSuccess = function(ev) {
|
||||||
|
this.togglePrompt()
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater.prototype.togglePrompt = function () {
|
||||||
|
if (this.options.maxItems != 0) {
|
||||||
|
var repeatedItems = this.$el.find('> .field-repeater-items > .field-repeater-item').length,
|
||||||
|
$addItemBtn = this.$el.find('> .field-repeater-add-item')
|
||||||
|
|
||||||
|
if (repeatedItems >= this.options.maxItems) {
|
||||||
|
$addItemBtn.hide()
|
||||||
|
} else if (repeatedItems < this.options.maxItems) {
|
||||||
|
$addItemBtn.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater.prototype.toggleCollapse = function(ev) {
|
Repeater.prototype.toggleCollapse = function(ev) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user