Add "styles" for repeater widgets (#4877)

Can be one of three values:
- "default": Shows all repeater items expanded on load.
- "collapsed": Shows all repeater items collapsed on load.
- "accordion": Shows only the first repeater item expanded on load. When another item is clicked, all other open items are collapsed.

Implements  #4801. Refs: https://github.com/rainlab/builder-plugin/issues/165, #2631
This commit is contained in:
Ben Thomson 2020-02-02 09:12:01 +08:00 committed by GitHub
parent 45dde59b5f
commit 3f982c25c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 3 deletions

View File

@ -43,6 +43,15 @@ class Repeater extends FormWidgetBase
*/
public $maxItems;
/**
* @var string The style of the repeater. Can be one of three values:
* - "default": Shows all repeater items expanded on load.
* - "collapsed": Shows all repeater items collapsed on load.
* - "accordion": Shows only the first repeater item expanded on load. When another item is clicked, all other open
* items are collapsed.
*/
public $style;
//
// Object properties
//
@ -101,6 +110,7 @@ class Repeater extends FormWidgetBase
$this->fillFromConfig([
'form',
'style',
'prompt',
'sortable',
'titleFrom',
@ -156,6 +166,7 @@ class Repeater extends FormWidgetBase
$this->vars['titleFrom'] = $this->titleFrom;
$this->vars['minItems'] = $this->minItems;
$this->vars['maxItems'] = $this->maxItems;
$this->vars['style'] = $this->style;
$this->vars['useGroups'] = $this->useGroups;
$this->vars['groupDefinitions'] = $this->groupDefinitions;

View File

@ -35,7 +35,8 @@
sortableContainer: 'ul.field-repeater-items',
titleFrom: null,
minItems: null,
maxItems: null
maxItems: null,
style: 'default',
}
Repeater.prototype.init = function() {
@ -49,6 +50,7 @@
this.$el.one('dispose-control', this.proxy(this.dispose))
this.togglePrompt()
this.applyStyle()
}
Repeater.prototype.dispose = function() {
@ -157,6 +159,13 @@
ev.preventDefault()
if (this.getStyle() === 'accordion') {
if (isCollapsed) {
this.expand($item)
}
return
}
if (ev.ctrlKey || ev.metaKey) {
isCollapsed ? this.expandAll() : this.collapseAll()
}
@ -167,7 +176,7 @@
Repeater.prototype.collapseAll = function() {
var self = this,
items = $('.field-repeater-item', this.$el)
items = $(this.$el).children('.field-repeater-items').children('.field-repeater-item')
$.each(items, function(key, item){
self.collapse($(item))
@ -176,7 +185,7 @@
Repeater.prototype.expandAll = function() {
var self = this,
items = $('.field-repeater-item', this.$el)
items = $(this.$el).children('.field-repeater-items').children('.field-repeater-item')
$.each(items, function(key, item){
self.expand($(item))
@ -189,6 +198,9 @@
}
Repeater.prototype.expand = function($item) {
if (this.getStyle() === 'accordion') {
this.collapseAll()
}
$item.removeClass('collapsed')
}
@ -229,6 +241,36 @@
return defaultText
}
Repeater.prototype.getStyle = function() {
var style = 'default';
// Validate style
if (this.options.style && ['collapsed', 'accordion'].indexOf(this.options.style) !== -1) {
style = this.options.style
}
return style;
}
Repeater.prototype.applyStyle = function() {
var style = this.getStyle(),
self = this,
items = $(this.$el).children('.field-repeater-items').children('.field-repeater-item')
$.each(items, function(key, item) {
switch (style) {
case 'collapsed':
self.collapse($(item))
break
case 'accordion':
if (key !== 0) {
self.collapse($(item))
}
break
}
})
}
// FIELD REPEATER PLUGIN DEFINITION
// ============================

View File

@ -3,6 +3,7 @@
<?= $titleFrom ? 'data-title-from="'.$titleFrom.'"' : '' ?>
<?= $minItems ? 'data-min-items="'.$minItems.'"' : '' ?>
<?= $maxItems ? 'data-max-items="'.$maxItems.'"' : '' ?>
<?= $style ? 'data-style="'.$style.'"' : '' ?>
data-sortable-container="#<?= $this->getId('items') ?>"
data-sortable-handle=".<?= $this->getId('items') ?>-handle">