From 3aa251db4e400a719af477aa7e397213503399fe Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 28 Feb 2017 20:43:08 -0600 Subject: [PATCH] Client side enforcement of repeater maxitems Adds client side enforcement of the max items property of the repeater form widget --- .../repeater/assets/js/repeater.js | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/modules/backend/formwidgets/repeater/assets/js/repeater.js b/modules/backend/formwidgets/repeater/assets/js/repeater.js index 68fa766fe..e21451fdd 100644 --- a/modules/backend/formwidgets/repeater/assets/js/repeater.js +++ b/modules/backend/formwidgets/repeater/assets/js/repeater.js @@ -33,25 +33,28 @@ Repeater.DEFAULTS = { sortableHandle: '.repeater-item-handle', sortableContainer: 'ul.field-repeater-items', - titleFrom: null + titleFrom: null, + maxItems: null } Repeater.prototype.init = function() { this.bindSorting() - this.$el.on('ajaxDone', '[data-repeater-remove]', this.proxy(this.onRemoveItemSuccess)) - this.$el.on('ajaxDone', '[data-repeater-add]', this.proxy(this.onAddItemSuccess)) + this.$el.on('ajaxDone', '> .field-repeater-items > .field-repeater-item > .repeater-item-remove > [data-repeater-remove]', this.proxy(this.onRemoveItemSuccess)) + 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.one('dispose-control', this.proxy(this.dispose)) + + this.togglePrompt() } Repeater.prototype.dispose = function() { this.$sortable.sortable('destroy') - - this.$el.off('ajaxDone', '[data-repeater-remove]', this.proxy(this.onRemoveItemSuccess)) - this.$el.off('ajaxDone', '[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('ajaxDone', '> .field-repeater-items > .field-repeater-item > .repeater-item-remove > [data-repeater-remove]', this.proxy(this.onRemoveItemSuccess)) + this.$el.off('ajaxDone', '> .field-repeater-add-item > [data-repeater-add]', this.proxy(this.onAddItemSuccess)) + 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.removeData('oc.repeater') @@ -76,13 +79,27 @@ this.$sortable.sortable(sortableOptions) } - + Repeater.prototype.onRemoveItemSuccess = function(ev) { $(ev.target).closest('.field-repeater-item').remove() + this.togglePrompt() } - // This fires twice, not sure why 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) {