Improvements to repeater collapsing

Removed the expand all, collapse all buttons, they are a bit too bulky so have been replaced with the standard CTRL+click behavior.
Added foundation library to repeater.js
Add "titleFrom" option to specify which input to use for the collapsed title
Styling improvements

Refs #2632 + #2631
This commit is contained in:
Samuel Georges 2017-01-28 11:59:28 +11:00
parent 4dbe172a43
commit e7609aa5e8
4 changed files with 133 additions and 148 deletions

View File

@ -1,27 +1,6 @@
.field-repeater {
padding-top: 5px;
}
.field-repeater .field-repeater-buttons {
text-align: right;
margin-bottom: 10px;
margin-top: -15px;
font-size: 12px;
}
.field-repeater .field-repeater-buttons * {
text-align: left;
}
.field-repeater .field-repeater-buttons .item {
color: #000000;
opacity: 0.5;
line-height: 20px;
margin: 0 10px;
display: inline-block;
}
.field-repeater .field-repeater-buttons .item:hover,
.field-repeater .field-repeater-buttons .item:focus {
opacity: 0.7;
text-decoration: none;
}
.field-repeater ul.field-repeater-items,
.field-repeater li.field-repeater-item {
padding: 0;
@ -40,6 +19,9 @@
.field-repeater ul.field-repeater-items > li.dragged .repeater-item-remove {
opacity: 0;
}
.field-repeater ul.field-repeater-items > li.dragged .repeater-item-collapsed-title {
top: 5px;
}
.field-repeater ul.field-repeater-items > li.placeholder {
display: block;
position: relative;
@ -67,8 +49,6 @@
padding-left: 15px;
border-left: 1px solid #dbdee0;
min-height: 30px;
-webkit-transition: all 0.5s;
transition: all 0.5s;
}
.field-repeater li.field-repeater-item:before {
color: #bdc3c7;
@ -95,33 +75,11 @@
.field-repeater li.field-repeater-item.collapsed .repeater-item-collapsed-title {
display: block;
}
.field-repeater li.field-repeater-item .repeater-item-collapse {
position: absolute;
top: -10px;
right: 40px;
height: 20px;
z-index: 90;
font-size: 12px;
}
.field-repeater li.field-repeater-item .repeater-item-collapse a {
-webkit-transition: all 0.3s;
transition: all 0.3s;
color: #000000;
opacity: 0.5;
line-height: 20px;
margin: 0 10px;
display: block;
float: left;
}
.field-repeater li.field-repeater-item .repeater-item-collapse a:hover,
.field-repeater li.field-repeater-item .repeater-item-collapse a:focus {
opacity: 0.7;
text-decoration: none;
}
.field-repeater li.field-repeater-item .repeater-item-collapsed-title {
display: none;
top: -7px;
top: -5px;
position: absolute;
font-size: 13px;
}
.field-repeater li.field-repeater-item .field-repeater-form {
position: relative;
@ -150,18 +108,43 @@
.field-repeater li.field-repeater-item .repeater-item-handle:hover {
color: #999;
}
.field-repeater li.field-repeater-item .repeater-item-collapse {
position: absolute;
top: -9px;
right: 22px;
z-index: 90;
}
.field-repeater li.field-repeater-item .repeater-item-collapse a,
.field-repeater li.field-repeater-item .repeater-item-collapse button {
-webkit-transition: transform 0.3s;
transition: transform 0.3s;
color: #bdc3c7;
line-height: 20px;
display: block;
font-size: 12px;
}
.field-repeater li.field-repeater-item .repeater-item-collapse a:hover,
.field-repeater li.field-repeater-item .repeater-item-collapse button:hover,
.field-repeater li.field-repeater-item .repeater-item-collapse a:focus,
.field-repeater li.field-repeater-item .repeater-item-collapse button:focus {
color: #999;
text-decoration: none;
}
.field-repeater li.field-repeater-item .repeater-item-remove {
position: absolute;
top: -10px;
right: 0;
z-index: 90;
}
.field-repeater li.field-repeater-item .repeater-item-collapse,
.field-repeater li.field-repeater-item .repeater-item-handle,
.field-repeater li.field-repeater-item .repeater-item-remove {
width: 20px;
height: 20px;
text-align: center;
}
.field-repeater li.field-repeater-item:hover .repeater-item-collapse,
.field-repeater li.field-repeater-item:active .repeater-item-collapse,
.field-repeater li.field-repeater-item:hover .repeater-item-handle,
.field-repeater li.field-repeater-item:active .repeater-item-handle,
.field-repeater li.field-repeater-item:hover .repeater-item-remove,

View File

@ -6,14 +6,14 @@
* - data-option="value" - an option with a value
*
* JavaScript API:
* $('a#someElement').fieldRepeater({ option: 'value' })
*
* Dependences:
* - Some other plugin (filename.js)
* $('a#someElement').fieldRepeater({...})
*/
+function ($) { "use strict";
var Base = $.oc.foundation.base,
BaseProto = Base.prototype
// FIELD REPEATER CLASS DEFINITION
// ============================
@ -22,23 +22,46 @@
this.$el = $(element)
this.$sortable = $(options.sortableContainer, this.$el)
// Init
$.oc.foundation.controlUtils.markDisposable(element)
Base.call(this)
this.init()
}
Repeater.prototype = Object.create(BaseProto)
Repeater.prototype.constructor = Repeater
Repeater.DEFAULTS = {
sortableHandle: '.repeater-item-handle',
sortableContainer: 'ul.field-repeater-items'
sortableContainer: 'ul.field-repeater-items',
titleFrom: null
}
Repeater.prototype.init = function() {
// Init with no arguments
this.bindSorting()
var self = this
this.$el.on('click', '.repeater-item-collapse-one', self.toggleCollapse)
this.$el.on('click', '.repeater-collapse-all', self.collapseAll)
this.$el.on('click', '.repeater-expand-all', self.expandAll)
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))
}
Repeater.prototype.dispose = function() {
this.$sortable.sortable('destroy')
this.$el.off('click', '> ul > li > .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')
this.$el = null
this.$sortable = null
this.options = null
BaseProto.dispose.call(this)
}
// Deprecated
Repeater.prototype.unbind = function() {
this.dispose()
}
Repeater.prototype.bindSorting = function() {
@ -50,50 +73,66 @@
this.$sortable.sortable(sortableOptions)
}
Repeater.prototype.unbind = function() {
this.$sortable.sortable('destroy')
this.$el.removeData('oc.repeater')
}
Repeater.prototype.toggleCollapse = function(ev) {
var $item = $(ev.target).closest('.field-repeater-item'),
isCollapsed = $item.hasClass('collapsed')
Repeater.prototype.toggleCollapse = function() {
var $item = $(this).closest('.field-repeater-item')
if ($item.hasClass('collapsed')) {
Repeater.prototype.expand($item)
} else {
Repeater.prototype.collapse($item)
if (event.ctrlKey || event.metaKey) {
isCollapsed ? this.expandAll() : this.collapseAll()
}
else {
isCollapsed ? this.expand($item) : this.collapse($item)
}
}
Repeater.prototype.collapseAll = function() {
var items = $(this).closest('.field-repeater').find('.field-repeater-item')
var self = this,
items = $('.field-repeater-item', this.$el)
$.each(items, function(key, item){
Repeater.prototype.collapse($(item))
self.collapse($(item))
})
}
Repeater.prototype.expandAll = function() {
var items = $(this).closest('.field-repeater').find('.field-repeater-item')
var self = this,
items = $('.field-repeater-item', this.$el)
$.each(items, function(key, item){
Repeater.prototype.expand($(item))
self.expand($(item))
})
}
Repeater.prototype.collapse = function($item) {
$item.addClass('collapsed')
var $textInput = $item.find('input[type=text]').first()
if($textInput.length) {
$item.find('.repeater-item-collapsed-title').text($textInput.val());
}
$('.repeater-item-collapsed-title', $item).text(this.getCollapseTitle($item));
}
Repeater.prototype.expand = function($item) {
$item.removeClass('collapsed')
}
Repeater.prototype.getCollapseTitle = function($item) {
var $target,
defaultText = ''
if (this.options.titleFrom) {
$target = $('[data-field-name="'+this.options.titleFrom+'"]')
if (!$target.length) {
$target = $item
}
}
else {
$target = $item
}
var $textInput = $('input[type=text]:first', $target)
if ($textInput.length) {
return $textInput.val()
}
return defaultText
}
// FIELD REPEATER PLUGIN DEFINITION
// ============================
@ -131,4 +170,4 @@
$('[data-control="fieldrepeater"]').fieldRepeater()
});
}(window.jQuery);
}(window.jQuery);

View File

@ -1,33 +1,8 @@
@import "../../../../assets/less/core/boot.less";
.field-repeater {
padding-top: 5px;
.field-repeater-buttons {
text-align: right;
margin-bottom: 10px;
margin-top: -15px;
font-size: 12px;
* {
text-align: left;
}
a {
color: #000000;
opacity: 0.5;
line-height: 20px;
margin:0 10px;
display: inline-block;
}
a:hover,
a:focus {
opacity: 0.7;
text-decoration: none;
}
}
ul.field-repeater-items,
li.field-repeater-item {
padding: 0;
@ -48,6 +23,10 @@
.repeater-item-remove {
opacity: 0;
}
.repeater-item-collapsed-title {
top: 5px;
}
}
&.placeholder {
@ -73,8 +52,6 @@
padding-left: 15px;
border-left: 1px solid #dbdee0;
min-height: 30px;
-webkit-transition: all 0.5s;
transition: all 0.5s;
&:before {
color: #bdc3c7;
@ -96,42 +73,16 @@
}
}
.repeater-item-collapsed-title{
.repeater-item-collapsed-title {
display: block;
}
}
.repeater-item-collapse {
position: absolute;
top: -10px;
right: 40px;
height: 20px;
z-index: 90;
font-size: 12px;
a,
button {
-webkit-transition: all 0.3s;
transition: all 0.3s;
color: #000000;
opacity: 0.5;
line-height: 20px;
margin:0 10px;
display: block;
float: left;
&:hover,
&:focus {
opacity: 0.7;
text-decoration: none;
}
}
}
.repeater-item-collapsed-title{
.repeater-item-collapsed-title {
display: none;
top: -7px;
top: -5px;
position: absolute;
font-size: 13px;
}
.field-repeater-form {
@ -155,6 +106,27 @@
}
}
.repeater-item-collapse {
position: absolute;
top: -9px;
right: 22px;
z-index: 90;
a, button {
.transition(~'transform 0.3s');
color: #bdc3c7;
line-height: 20px;
display: block;
font-size: 12px;
&:hover,
&:focus {
color: #999;
text-decoration: none;
}
}
}
.repeater-item-remove {
position: absolute;
top: -10px;
@ -162,6 +134,7 @@
z-index: 90;
}
.repeater-item-collapse,
.repeater-item-handle,
.repeater-item-remove {
width: 20px;
@ -170,6 +143,7 @@
}
&:hover, &:active {
.repeater-item-collapse,
.repeater-item-handle,
.repeater-item-remove {
opacity: 1;
@ -209,5 +183,4 @@
> a { color: #bdc3c7;}
}
}
}
}

View File

@ -3,16 +3,6 @@
data-sortable-container="#<?= $this->getId('items') ?>"
data-sortable-handle=".<?= $this->getId('items') ?>-handle">
<div class="field-repeater-buttons">
<a href="javascript:;" class="item repeater-collapse-all">
<?= e(trans('backend::lang.dashboard.collapse_all')) ?>
</a>
<a href="javascript:;" class="item repeater-expand-all">
<?= e(trans('backend::lang.dashboard.expand_all')) ?>
</a>
</div>
<ul id="<?= $this->getId('items') ?>" class="field-repeater-items">
<?php foreach ($this->formWidgets as $index => $widget): ?>
<?= $this->makePartial('repeater_item', [