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:
@@ -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
|
||||
|
@@ -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'];
|
||||
|
@@ -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
@@ -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')
|
||||
)
|
||||
));
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user