1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-08 07:47:00 +02:00

Repeater updates continued with a complete refactoring of the InputfieldRepeater.js file. This update also corrects the depth-dragging issues that were present in the last commit (issues were especially noticable dragging when using AdminThemeReno). Also adds a repeater open all/close all function per processwire/processwire-requests#33 - to use it, double click the "on/off" toggle icon that appears next to the trash icon.

This commit is contained in:
Ryan Cramer
2016-12-08 14:02:43 -05:00
parent d92674fd4a
commit 6027e87a5e
9 changed files with 816 additions and 541 deletions

View File

@@ -69,7 +69,7 @@
* @property InputfieldWrapper|null $parent The parent InputfieldWrapper for this Inputfield or null if not set. #pw-internal
* @property null|bool|Fieldtype $hasFieldtype The Fieldtype using this Inputfield, or boolean false when known not to have a Fieldtype, or null when not known. #pw-group-other
* @property bool|null $useLanguages When multi-language support active, can be set to true to make it provide inputs for each language, where supported (default=false). #pw-group-behavior
* @property null|bool $entityEncodeLabel Set to boolean false to specifically disable entity encoding of field header/label (default=true). #pw-group-output
* @property null|bool|int $entityEncodeLabel Set to boolean false to specifically disable entity encoding of field header/label, or set to a Inputfield::textFormat constant. (default=true). #pw-group-output
* @property null|bool $entityEncodeText Set to boolean false to specifically disable entity encoding for other text: description, notes, etc. (default=true). #pw-group-output
* @property int $renderValueFlags Options that can be applied to renderValue mode, see "renderValue" constants (default=0). #pw-group-output
* @property string $wrapClass Optional class name (CSS) to apply to the HTML element wrapping the Inputfield. #pw-group-other

View File

@@ -504,7 +504,13 @@ class InputfieldWrapper extends Inputfield implements \Countable, \IteratorAggre
if($label || $quietMode) {
$for = $inputfield->getSetting('skipLabel') || $quietMode ? '' : $inputfield->attr('id');
// if $inputfield has a property of entityEncodeLabel with a value of boolean FALSE, we don't entity encode
if($inputfield->getSetting('entityEncodeLabel') !== false) $label = $inputfield->entityEncode($label);
$entityEncodeLabel = $inputfield->getSetting('entityEncodeLabel');
if(is_int($entityEncodeLabel) && $entityEncodeLabel >= Inputfield::textFormatBasic) {
// uses an Inputfield::textFormat constant
$label = $inputfield->entityEncode($label, $entityEncodeLabel);
} else if($entityEncodeLabel !== false) {
$label = $inputfield->entityEncode($label);
}
$icon = $inputfield->getSetting('icon');
$icon = $icon ? str_replace('{name}', $this->wire('sanitizer')->name(str_replace(array('icon-', 'fa-'), '', $icon)), $markup['item_icon']) : '';
$toggle = $collapsed == Inputfield::collapsedNever ? '' : $markup['item_toggle'];

View File

@@ -2,19 +2,39 @@
margin-bottom: 1em; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader {
line-height: 1em;
padding: 0.5em; }
padding: 0.5em 0 0.5em 0.4em;
white-space: nowrap;
overflow: hidden;
position: relative; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader .InputfieldRepeaterItemLabel {
display: inline-block;
padding-left: 0.25em; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader .InputfieldRepeaterItemControls {
padding-right: 0.5em;
padding-left: 0.5em;
margin-top: 0.5em;
position: absolute;
top: 0;
right: 0;
z-index: 1;
display: block;
white-space: nowrap;
height: 100%; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader .InputfieldRepeaterItemControls .InputfieldRepeaterClone,
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader .InputfieldRepeaterItemControls .InputfieldRepeaterToggle,
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader .InputfieldRepeaterItemControls .InputfieldRepeaterTrash,
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader .InputfieldRepeaterItemControls .toggle-icon {
cursor: pointer;
float: right; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader .InputfieldRepeaterItemControls .InputfieldRepeaterTrash {
padding-right: 3px; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader .InputfieldRepeaterItemControls .InputfieldRepeaterToggle {
margin-right: 1em; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader .InputfieldRepeaterItemControls .InputfieldRepeaterClone {
margin-right: 1em; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader .toggle-icon {
line-height: 1em;
margin-right: 0.5em; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader > .InputfieldRepeaterClone, .Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader > .InputfieldRepeaterToggle, .Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader > .InputfieldRepeaterTrash {
cursor: pointer;
float: right; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader > .InputfieldRepeaterTrash {
padding-right: 3px; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader > .InputfieldRepeaterToggle {
margin-right: 1em; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem > .InputfieldHeader > .InputfieldRepeaterClone {
margin-right: 1em; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldStateCollapsed > .InputfieldHeader {
opacity: 0.90; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldStateCollapsed > .InputfieldHeader:hover {
@@ -23,8 +43,10 @@
opacity: 0.7; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldRepeaterOff > .InputfieldHeader {
opacity: 0.5; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldRepeaterOff > .InputfieldHeader:not(:hover) {
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldRepeaterOff > .InputfieldHeader:not(:hover) > .InputfieldRepeaterItemLabel {
text-decoration: line-through; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem.InputfieldRepeaterDeletePending > .InputfieldHeader > .InputfieldRepeaterItemLabel {
text-decoration: line-through; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem.InputfieldRepeaterItemLoading {
margin-bottom: 1em; }
.Inputfields .InputfieldRepeater .InputfieldRepeaterItem.InputfieldStateCollapsed > .InputfieldContent {
@@ -44,6 +66,7 @@
.InputfieldRepeater ul.Inputfields + .InputfieldRepeaterAddItem {
margin-top: 0; }
.InputfieldRepeater .InputfieldRepeaterDrag {
display: inline-block;
cursor: ns-resize;
opacity: 0.7;
line-height: 1em; }

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -335,8 +335,12 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
$loaded->attr('value', $isLoaded ? 1 : 0);
$wrap = $this->wire('modules')->get('InputfieldFieldset');
$wrap->addClass('InputfieldRepeaterItem');
$wrap->label = $this->renderRepeaterLabel($label, ++$cnt, $page);
$wrap->addClass('InputfieldRepeaterItem InputfieldNoFocus');
$wrap->entityEncodeLabel = false;
$wrap->label =
"<span class='InputfieldRepeaterItemLabel'>" .
$this->entityEncode($this->renderRepeaterLabel($label, ++$cnt, $page)) .
"</span>";
$wrap->name = "repeater_item_{$page->id}";
$wrap->wrapAttr('data-page', $page->id);
$wrap->wrapAttr('data-type', $this->getRepeaterItemType($page));
@@ -400,6 +404,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
// create a new/blank item to be used as a template for any new items added
if(!$itemID) {
/** @var InputfieldWrapper $wrap */
$wrap = $this->wire('modules')->get('InputfieldFieldset');
$wrap->label = $this->renderRepeaterLabel($label, ++$cnt, new NullPage());
$wrap->class = 'InputfieldRepeaterItem InputfieldRepeaterNewItem';
@@ -540,10 +545,12 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
$this->wire('config')->js('InputfieldRepeater', array(
'editorUrl' => $editorUrl,
'labels' => array(
'remove' => $this->_x('Delete this item', 'repeater-item-action'),
'remove' => $this->_x('Click to delete this item, or double-click to delete all', 'repeater-item-action'),
'removeAll' => $this->_x('Delete all items?', 'repeater-item-action'),
'toggle' => $this->_x('Toggle published/unpublished', 'repeater-item-action'),
'clone' => $this->_x('Clone this item?', 'repeater-item-action')
'toggle' => $this->_x('Click to turn item on/off, or double-click to open/collapse all items', 'repeater-item-action'),
'clone' => $this->_x('Clone this item?', 'repeater-item-action'),
'openAll' => $this->_x('Open all items?', 'repeater-item-action'),
'collapseAll' => $this->_x('Collapse all items?', 'repeater-item-action')
)
));

View File

@@ -7,28 +7,50 @@
.InputfieldRepeaterItem > .InputfieldHeader {
line-height: 1em;
padding: 0.5em;
padding: 0.5em 0 0.5em 0.4em;
white-space: nowrap;
overflow: hidden;
position: relative;
.InputfieldRepeaterItemLabel {
display: inline-block;
padding-left: 0.25em;
}
.InputfieldRepeaterItemControls {
padding-right: 0.5em;
padding-left: 0.5em;
margin-top: 0.5em;
position: absolute;
top: 0;
right: 0;
z-index: 1;
display: block;
white-space: nowrap;
height: 100%;
.InputfieldRepeaterClone,
.InputfieldRepeaterToggle,
.InputfieldRepeaterTrash,
.toggle-icon {
cursor: pointer;
float: right;
}
.InputfieldRepeaterTrash {
padding-right: 3px;
}
.InputfieldRepeaterToggle {
margin-right: 1em;
}
.InputfieldRepeaterClone {
margin-right: 1em;
}
}
.toggle-icon {
line-height: 1em;
margin-right: 0.5em;
}
& > .InputfieldRepeaterClone,
& > .InputfieldRepeaterToggle,
& > .InputfieldRepeaterTrash {
cursor: pointer;
float: right;
}
& > .InputfieldRepeaterTrash {
padding-right: 3px;
}
& > .InputfieldRepeaterToggle {
margin-right: 1em;
}
& > .InputfieldRepeaterClone {
margin-right: 1em;
}
}
.InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending) {
@@ -48,12 +70,16 @@
&.InputfieldRepeaterOff > .InputfieldHeader {
// off items faded yet even more
opacity: 0.5;
&:not(:hover) {
&:not(:hover) > .InputfieldRepeaterItemLabel {
text-decoration: line-through;
}
}
}
.InputfieldRepeaterItem.InputfieldRepeaterDeletePending > .InputfieldHeader > .InputfieldRepeaterItemLabel {
text-decoration: line-through;
}
.InputfieldRepeaterItem.InputfieldRepeaterItemLoading {
// override the margin-bottom 1.25em from admin theme stylesheet, so margin isn't showing while item is loading
margin-bottom: 1em;
@@ -82,6 +108,7 @@
position: relative;
}
.InputfieldRepeaterAddItem input {
// count of added items hidden
position: absolute;
@@ -96,6 +123,7 @@
.InputfieldRepeaterDrag {
// draggable icon for repeater items
display: inline-block;
cursor: ns-resize;
opacity: 0.7;
line-height: 1em;

View File

@@ -351,4 +351,11 @@
top: -1.1em;
bottom: auto; }
.AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input textarea:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="date"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="datetime-local"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="email"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="month"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="number"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="password"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="search"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="tel"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="text"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="time"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="url"]:focus, .AdminThemeReno .vex.vex-theme-default .vex-dialog-form .vex-dialog-input input[type="week"]:focus {
-moz-box-shadow: inset 0 0 0 2px #86d7c1;
-webkit-box-shadow: inset 0 0 0 2px #86d7c1;
box-shadow: inset 0 0 0 2px #86d7c1; }
.AdminThemeReno .vex.vex-theme-default .vex-dialog-button.vex-dialog-button-primary {
background: #3eb998; }
/*# sourceMappingURL=vex-theme-default.css.map */

View File

@@ -7,6 +7,7 @@
$blue: #3288e6
$green: #93BF0D // RJC
$reno-green: #3eb998 // RJC
.vex.vex-theme-default
padding-top: 160px
@@ -128,3 +129,16 @@ $green: #93BF0D // RJC
border-top-color: #bbb
top: -1.1em
bottom: auto
.AdminThemeReno
.vex.vex-theme-default
.vex-dialog-form
.vex-dialog-input
textarea, input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"]
&:focus
+box-shadow(inset 0 0 0 2px lighten($reno-green, 20%)) // RJC
.vex-dialog-button
&.vex-dialog-button-primary
background: $reno-green // RJC