diff --git a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.css b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.css
index f7b3d624..4d0903ed 100644
--- a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.css
+++ b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.css
@@ -1 +1 @@
-.Inputfields .InputfieldRepeater>.InputfieldContent>ul.Inputfields{margin-bottom:1em}.Inputfields .InputfieldRepeater>.InputfieldContent>ul.Inputfields:last-child{margin-bottom:0}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader{line-height:1em;padding:.5em 0 .5em .4em;white-space:nowrap;overflow:hidden;position:relative}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader .InputfieldRepeaterItemLabel,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader .InputfieldRepeaterItemControls{display:none}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemLabel{display:inline-block;padding-left:.25em}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls{display:block;padding-right:.5em;padding-left:.5em;margin-top:.5em;position:absolute;top:0;right:0;z-index:1;display:block;white-space:nowrap;height:100%}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterSettingsToggle,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterClone,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterToggle,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterTrash,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .toggle-icon{cursor:pointer;float:right}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterTrash{padding-right:3px}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterToggle{margin-right:1em}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterClone{margin-right:1em}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterSettingsToggle{margin-right:1em}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .pw-icon-disabled{opacity:.3}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .toggle-icon{line-height:1em;margin-right:.5em}.Inputfields .InputfieldRepeater .InputfieldStateCollapsed .InputfieldRepeaterSettingsToggle{display:none}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldStateCollapsed>.InputfieldHeader{opacity:.9}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldStateCollapsed>.InputfieldHeader:hover{opacity:1}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldRepeaterUnpublished>.InputfieldHeader{opacity:.7}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldRepeaterOff>.InputfieldHeader{opacity:.5}.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{display:none !important}.Inputfields .InputfieldRepeater .InputfieldRepeaterNewItem{display:none}.Inputfields .InputfieldRepeater .InputfieldRepeaterDelete{display:none}.Inputfields .InputfieldRepeater.InputfieldRepeaterSingle>.InputfieldContent>.Inputfields{margin-bottom:0}.Inputfields .InputfieldRepeater.InputfieldRepeaterSingle>.InputfieldContent>.Inputfields>.InputfieldRepeaterItem{margin-bottom:0}.Inputfields .InputfieldRepeater.InputfieldRepeaterSingle>.InputfieldContent>.Inputfields>.InputfieldRepeaterItem>.InputfieldHeader{display:none}.InputfieldRepeater{z-index:1}.InputfieldRepeater .InputfieldWrapper,.InputfieldRepeater .InputfieldWrapper>.Inputfields{margin-top:0 !important}.InputfieldRepeater ul.ui-sortable>.InputfieldRepeaterItem>.InputfieldHeader{position:relative}.InputfieldRepeater .InputfieldRepeaterAddItem input{display:none !important}.InputfieldRepeater ul.Inputfields+.InputfieldRepeaterAddItem{margin-top:0}.InputfieldRepeater .InputfieldRepeaterDrag{display:inline-block;cursor:ns-resize;opacity:.7;line-height:1em}.InputfieldRepeater .InputfieldRepeaterDrag:hover{cursor:move;opacity:1}.InputfieldRepeater.InputfieldRenderValueMode .InputfieldRepeaterDrag{margin-right:.25em;opacity:.5}.InputfieldRepeater.InputfieldRenderValueMode .InputfieldRepeaterDrag:hover{cursor:not-allowed;opacity:.5}.AdminThemeReno .InputfieldRepeaterItem>.InputfieldHeader .ui-priority-secondary{color:rgba(255,255,255,.8) !important}
+.Inputfields .InputfieldRepeater>.InputfieldContent>ul.Inputfields{margin-bottom:1em}.Inputfields .InputfieldRepeater>.InputfieldContent>ul.Inputfields:last-child{margin-bottom:0}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader{line-height:1em;padding:.5em 0 .5em .4em;white-space:nowrap;overflow:hidden;position:relative}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader .InputfieldRepeaterItemLabel,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader .InputfieldRepeaterItemControls{display:none}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemLabel{display:inline-block;padding-left:.25em}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls{display:block;padding-right:.5em;padding-left:.5em;margin-top:.5em;position:absolute;top:0;right:0;z-index:1;display:block;white-space:nowrap;height:100%}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterSettingsToggle,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterClone,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterToggle,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterTrash,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterInsertBefore,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterInsertAfter,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .toggle-icon{cursor:pointer;float:right}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterSettingsToggle:hover,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterClone:hover,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterToggle:hover,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterTrash:hover,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterInsertBefore:hover,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterInsertAfter:hover,.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .toggle-icon:hover{opacity:.8}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterTrash{padding-right:3px}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterToggle{margin-right:1em}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterClone{margin-right:1em}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterInsertBefore{margin-right:.75em}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterInsertAfter{margin-right:1em}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .InputfieldRepeaterSettingsToggle{margin-right:1em}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .InputfieldRepeaterItemControls .pw-icon-disabled{opacity:.3}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem>.InputfieldHeader.InputfieldRepeaterHeaderInit .toggle-icon{line-height:1em;margin-right:.5em}.Inputfields .InputfieldRepeater>.InputfieldContent>.Inputfields>.InputfieldRepeaterInsertItem{opacity:.5}.Inputfields .InputfieldRepeater .InputfieldStateCollapsed .InputfieldRepeaterSettingsToggle{display:none}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldStateCollapsed>.InputfieldHeader{opacity:.9}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldStateCollapsed>.InputfieldHeader:hover{opacity:1}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldRepeaterUnpublished>.InputfieldHeader{opacity:.7}.Inputfields .InputfieldRepeater .InputfieldRepeaterItem:not(.InputfieldRepeaterDeletePending).InputfieldRepeaterOff>.InputfieldHeader{opacity:.5}.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{display:none !important}.Inputfields .InputfieldRepeater .InputfieldRepeaterNewItem{display:none}.Inputfields .InputfieldRepeater .InputfieldRepeaterDelete{display:none}.Inputfields .InputfieldRepeater.InputfieldRepeaterSingle>.InputfieldContent>.Inputfields{margin-bottom:0}.Inputfields .InputfieldRepeater.InputfieldRepeaterSingle>.InputfieldContent>.Inputfields>.InputfieldRepeaterItem{margin-bottom:0}.Inputfields .InputfieldRepeater.InputfieldRepeaterSingle>.InputfieldContent>.Inputfields>.InputfieldRepeaterItem>.InputfieldHeader{display:none}.InputfieldRepeater{z-index:1}.InputfieldRepeater .InputfieldWrapper,.InputfieldRepeater .InputfieldWrapper>.Inputfields{margin-top:0 !important}.InputfieldRepeater ul.ui-sortable>.InputfieldRepeaterItem>.InputfieldHeader{position:relative}.InputfieldRepeater .InputfieldRepeaterAddItem input{display:none !important}.InputfieldRepeater ul.Inputfields+.InputfieldRepeaterAddItem{margin-top:0}.InputfieldRepeater .InputfieldRepeaterDrag{display:inline-block;cursor:ns-resize;opacity:.7;line-height:1em}.InputfieldRepeater .InputfieldRepeaterDrag:hover{cursor:move;opacity:1}.InputfieldRepeater.InputfieldRenderValueMode .InputfieldRepeaterDrag{margin-right:.25em;opacity:.5}.InputfieldRepeater.InputfieldRenderValueMode .InputfieldRepeaterDrag:hover{cursor:not-allowed;opacity:.5}.AdminThemeReno .InputfieldRepeaterItem>.InputfieldHeader .ui-priority-secondary{color:rgba(255,255,255,.8) !important}
diff --git a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.js b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.js
index 8e82c926..2bc3a026 100644
--- a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.js
+++ b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.js
@@ -33,6 +33,18 @@ function InputfieldRepeater($) {
*/
var doubleClickTimer = null;
+ /**
+ * True when an ajax request is currently processing a newly added item
+ *
+ */
+ var currentlyAddingItem = false;
+
+ /**
+ * Timeout tracker for insert actions
+ *
+ */
+ var insertTimeout = null;
+
/*** EVENTS ********************************************************************************************/
@@ -313,6 +325,8 @@ function InputfieldRepeater($) {
*
*/
var eventAddLinkClick = function() {
+ currentlyAddingItem = true;
+
var $addLink = $(this);
var $inputfields = $addLink.parent('p').prev('ul.Inputfields');
var $inputfieldRepeater = $addLink.closest('.InputfieldRepeater');
@@ -320,13 +334,25 @@ function InputfieldRepeater($) {
var newItemTotal = 0; // for noAjaxAdd mode
var useAjax = $addLink.attr('data-noajax').length == 0;
var cloneID = $addLink.attr('data-clone');
+ var depth = 0;
+ var redoSortAll = false;
function addRepeaterItem($addItem) {
// make sure it has a unique ID
var id = $addItem.attr('id') + '_';
while($('#' + id).length > 0) id += '_';
$addItem.attr('id', id);
- $inputfields.append($addItem);
+ var $insertItem = $inputfields.children('.InputfieldRepeaterInsertItem');
+ if($insertItem.length) {
+ depth = getItemDepth($insertItem);
+ $addItem.addClass('InputfieldStateCollapsed')
+ var $toggleIcon = $addItem.children('.InputfieldHeader').find('.toggle-icon');
+ $toggleIcon.toggleClass($toggleIcon.attr('data-to'));
+ $insertItem.replaceWith($addItem);
+ redoSortAll = true;
+ } else {
+ $inputfields.append($addItem);
+ }
$addItem.css('display', 'block');
adjustItemLabel($addItem, true);
$addLink.trigger('repeateradd', [ $addItem ]);
@@ -341,10 +367,12 @@ function InputfieldRepeater($) {
if(newItemTotal > 0) {
if(newItemTotal > 1) $newItem = $newItem.slice(0, 1);
var $addItem = $newItem.clone(true);
+ if(depth) setItemDepth($addItem, depth);
addRepeaterItem($addItem);
$numAddInput.attr('value', newItemTotal);
checkMinMax($inputfieldRepeater);
}
+ currentlyAddingItem = false;
return false;
}
@@ -390,10 +418,21 @@ function InputfieldRepeater($) {
// next line can remove 9/2019, as 'cloned' support will have been in InputfieldTable for awhile
$addItem.find('.InputfieldTableRowID').val(0);
}
- $addItem.find('.InputfieldRepeaterSort').val($inputfields.children().length);
- $('html, body').animate({
- scrollTop: $addItem.offset().top
- }, 500, 'swing');
+ if(redoSortAll) {
+ $inputfields.children('.InputfieldRepeaterItem').each(function(n) {
+ setItemSort($(this), n);
+ });
+ } else {
+ setItemSort($addItem, $inputfields.children().length);
+ }
+ if(depth) setItemDepth($addItem, depth);
+ if($addItem.hasClass('InputfieldStateCollapsed')) {
+ // ok
+ } else {
+ $('html, body').animate({
+ scrollTop: $addItem.offset().top
+ }, 500, 'swing');
+ }
updateState($addItem);
checkMinMax($inputfieldRepeater);
updateAccordion($addItem);
@@ -404,6 +443,8 @@ function InputfieldRepeater($) {
});
}
runScripts(data);
+
+ setTimeout(function() { currentlyAddingItem = false; }, 500);
});
return false;
@@ -445,6 +486,131 @@ function InputfieldRepeater($) {
});
return false;
};
+
+ /**
+ * Click the "insert before" button event
+ *
+ */
+ var eventInsertBeforeClick = function(e) {
+ var $item = $(this).closest('.InputfieldRepeaterItem');
+ eventInsertClick($item, true);
+ e.stopPropagation();
+ };
+
+ /**
+ * Click the "insert after" button event
+ *
+ */
+ var eventInsertAfterClick = function(e) {
+ var $item = $(this).closest('.InputfieldRepeaterItem');
+ eventInsertClick($item, false);
+ e.stopPropagation();
+ };
+
+ /**
+ * Handler for either insert before or insert after click events
+ *
+ */
+ function eventInsertClick($item, insertBefore) {
+ if(currentlyAddingItem) return false;
+ currentlyAddingItem = true;
+ if(insertTimeout) clearTimeout(insertTimeout);
+ var depth = getInsertItemDepth($item, insertBefore);
+ var $insertItem = $item.siblings('.InputfieldRepeaterInsertItem');
+ if($insertItem.length) {
+ $insertItem.remove();
+ }
+ var $placeholder = $item.siblings('.InputfieldRepeaterNewItem').clone()
+ .removeClass('.InputfieldRepeaterNewItem').addClass('InputfieldRepeaterInsertItem');
+ $placeholder.attr('id', $placeholder.attr('id') + '-placeholder');
+ $placeholder.find('.InputfieldHeader').html("");
+ if(insertBefore) {
+ $placeholder.insertBefore($item);
+ } else {
+ $placeholder.insertAfter($item);
+ }
+ if(depth > 0) setItemDepth($placeholder, depth);
+ $placeholder.show();
+ if(!insertBefore && !$item.hasClass('InputfieldStateCollapsed')) scrollToItem($placeholder);
+ $placeholder.children('.InputfieldHeader').effect('highlight', {}, 500);
+ // @todo the following line will need to be updated for matrix support
+ $item.parent('.Inputfields').siblings('.InputfieldRepeaterAddItem').find('.InputfieldRepeaterAddLink:eq(0)').click();
+ }
+
+ /**
+ * Event when mouseout of insert before/after action
+ *
+ */
+ var eventInsertMouseout = function(e) {
+ if(currentlyAddingItem) return;
+ if(insertTimeout) clearTimeout(insertTimeout);
+ var $action = $(this);
+ var $newItem = $action.data('newItem');
+ $action.removeClass('hov');
+ // var $newItem = $action.closest('.Inputfields').children('.InputfieldRepeaterInsertItem');
+ if($newItem && $newItem.length) {
+ if($newItem.hasClass('hov')) return;
+ $newItem.remove();
+ }
+ };
+
+ /**
+ * Event when mouseover of insert before/after action
+ *
+ */
+ var eventInsertMouseover = function(e) {
+
+ if(currentlyAddingItem) return;
+ if(insertTimeout) clearTimeout(insertTimeout);
+
+ var $action = $(this);
+ var insertBefore = $action.hasClass('InputfieldRepeaterInsertBefore');
+ var $item = $(this).closest('.InputfieldRepeaterItem');
+ var depth = 0;
+
+ $item.siblings('.InputfieldRepeaterInsertItem').remove();
+
+ var $newItem = $item.siblings('.InputfieldRepeaterNewItem').clone();
+ $newItem.addClass('InputfieldRepeaterInsertItem').attr('id', $newItem.attr('id') + '-insert');
+
+ if(insertBefore) {
+ depth = getInsertBeforeItemDepth($item);
+ $newItem.addClass('InputfieldRepeaterInsertItemBefore');//.insertBefore($item);
+ } else {
+ depth = getInsertAfterItemDepth($item);
+ $newItem.addClass('InputfieldRepeaterInsertItemAfter');//.insertAfter($item);
+ }
+
+ $newItem.find('.InputfieldRepeaterItemControls').hide();
+ $newItem.find('.InputfieldRepeaterItemLabel').text(ProcessWire.config.InputfieldRepeater.labels.insertHere);
+
+ $action.addClass('hov').data('newItem', $newItem);
+
+ setItemDepth($newItem, depth);
+
+ insertTimeout = setTimeout(function() {
+ insertTimeout = null;
+ if(!$action.hasClass('hov')) {
+ $newItem.remove();
+ return;
+ } else if(insertBefore) {
+ $newItem.insertBefore($item);
+ } else {
+ $newItem.addClass('hov').insertAfter($item);
+ }
+ //$newItem.addClass('hov');
+ $newItem.on('mouseover', function() {
+ $(this).addClass('hov');
+ }).on('click', function(e) {
+ e.stopPropagation();
+ eventInsertClick($item, insertBefore);
+ }).on('mouseout', function() {
+ $(this).removeClass('hov').remove();
+ });
+ $newItem.slideDown();
+ }, 1000);
+ };
+
/*** GENERAL FUNCTIONS **********************************************************************************/
@@ -487,7 +653,7 @@ function InputfieldRepeater($) {
});
if(useScroll && hasOpen) {
- $('html, body').animate({scrollTop: $item.offset().top - 10}, 0);
+ scrollToItem($item);
}
return true;
@@ -527,6 +693,25 @@ function InputfieldRepeater($) {
}
}
}
+
+ /*** SORT FUNCTIONS ***********************************************************************************/
+
+ function setItemSort($item, sort) {
+ var $input = getItemSortInput($item);
+ if($input.length) $input.val(sort);
+ }
+
+ function getItemSort($item) {
+ var $input = getItemSortInput($item);
+ if($input.length) return parseInt($input.val());
+ return -1;
+ }
+
+ function getItemSortInput($item) {
+ if(!$item.hasClass('InputfieldRepeaterItem')) $item = $item.closest('.InputfieldRepeaterItem');
+ return $item.children('.InputfieldContent').children('.Inputfields')
+ .children('.InputfieldRepeaterItemSort').find('.InputfieldRepeaterSort');
+ }
/*** DEPTH FUNCTIONS **********************************************************************************/
@@ -586,7 +771,7 @@ function InputfieldRepeater($) {
var $depthInput = $item.children('.InputfieldContent').children('.Inputfields')
.children('.InputfieldRepeaterItemDepth').find('input');
- if(!$depthInput.length) {
+ if(!$depthInput.length && !$item.hasClass('InputfieldRepeaterNewItem')) {
console.log('Cannot find depth input for ' + $item.attr('id'));
}
@@ -625,6 +810,39 @@ function InputfieldRepeater($) {
return parseInt($item.attr('data-depth'));
}
+ /**
+ * Get depth for a new item if it were to be inserted before/after given $contextItem
+ *
+ * @param $contextItem
+ * @param insertBefore
+ * @returns {Number}
+ *
+ */
+ function getInsertItemDepth($contextItem, insertBefore) {
+ var depth = 0;
+ if(insertBefore) {
+ depth = getItemDepth($contextItem);
+ } else {
+ var $nextItem = $contextItem.next('.InputfieldRepeaterItem');
+ depth = getItemDepth($contextItem);
+ if($nextItem.hasClass('InputfieldRepeaterNewItem')) {
+ // the default hidden new item is not useful for identifying depth
+ if(!$nextItem.hasClass('InputfieldRepeaterInsertItem')) $nextItem = null;
+ }
+ var nextDepth = $nextItem && $nextItem.length ? getItemDepth($nextItem) : depth;
+ if(nextDepth > depth) depth = nextDepth;
+ }
+ return depth;
+ }
+
+ function getInsertBeforeItemDepth($item) {
+ return getInsertItemDepth($item, true);
+ }
+
+ function getInsertAfterItemDepth($item) {
+ return getInsertItemDepth($item, false);
+ }
+
/**
* Get all depth children for given repeater item
*
@@ -815,6 +1033,8 @@ function InputfieldRepeater($) {
var $clone = $("").css('display', 'block');
var $delete = $("");
var $toggle = $("");
+ var $insertAfter = $("");
+ var $insertBefore = $("");
var cfg = ProcessWire.config.InputfieldRepeater;
var allowClone = !$inputfieldRepeater.hasClass('InputfieldRepeaterNoAjaxAdd');
var allowSettings = $inputfieldRepeater.hasClass('InputfieldRepeaterHasSettings');
@@ -823,6 +1043,8 @@ function InputfieldRepeater($) {
$toggle.attr('title', cfg.labels.toggle);
$delete.attr('title', cfg.labels.remove);
$clone.attr('title', cfg.labels.clone);
+ $insertBefore.attr('title', cfg.labels.insertBefore);
+ $insertAfter.attr('title', cfg.labels.insertAfter);
}
if(allowSettings) {
@@ -836,7 +1058,7 @@ function InputfieldRepeater($) {
var $item = $t.parent();
if($item.hasClass('InputfieldRepeaterNewItem')) {
// noAjaxAdd mode
- icon = 'fa-plus';
+ icon = 'fa-plus-circle';
$t.addClass('ui-priority-secondary');
}
$t.addClass('ui-state-default InputfieldRepeaterHeaderInit');
@@ -847,7 +1069,11 @@ function InputfieldRepeater($) {
.addClass($t.parent().hasClass('InputfieldRepeaterOff') ? 'fa-toggle-off' : 'fa-toggle-on');
var $deleteControl = $delete.clone(true);
var $collapseControl = $t.find('.toggle-icon');
+ var $insertBeforeControl = $insertBefore.clone(true);
+ var $insertAfterControl = $insertAfter.clone(true);
$controls.prepend($collapseControl);
+ $controls.prepend($insertBeforeControl);
+ $controls.prepend($insertAfterControl);
if($t.closest('.InputfieldRepeater').hasClass('InputfieldRepeaterHasSettings')) { // intentionally not using allowSettings var
var $settingsToggle = $("")
.attr('title', cfg.labels.settings);
@@ -858,7 +1084,6 @@ function InputfieldRepeater($) {
$controls.prepend($deleteControl);
$t.prepend($controls);
$controls.css('background-color', $t.css('background-color'));
-
}
adjustItemLabel($item, false);
});
@@ -1013,6 +1238,15 @@ function InputfieldRepeater($) {
}
}
+ /**
+ * Scroll to repeater item
+ *
+ * @param $item
+ */
+ function scrollToItem($item) {
+ $('html, body').animate({scrollTop: $item.offset().top - 10}, 250, 'swing');
+ }
+
/**
* Run any scripts in the given HTML ajax data since jQuery will strip them
*
@@ -1071,7 +1305,12 @@ function InputfieldRepeater($) {
.on('click', '.InputfieldRepeaterToggle', eventToggleClick)
.on('opened', '.InputfieldRepeaterItem', eventItemOpened)
.on('closed', '.InputfieldRepeaterItem', eventItemClosed)
- .on('openReady', '.InputfieldRepeaterItem', eventItemOpenReady);
+ .on('openReady', '.InputfieldRepeaterItem', eventItemOpenReady)
+ .on('click', '.InputfieldRepeaterInsertBefore', eventInsertBeforeClick)
+ .on('click', '.InputfieldRepeaterInsertAfter', eventInsertAfterClick)
+ .on('mouseover', '.InputfieldRepeaterInsertBefore', eventInsertMouseover)
+ .on('mouseover', '.InputfieldRepeaterInsertAfter', eventInsertMouseover)
+ .on('mouseout', '.InputfieldRepeaterInsertAfter', eventInsertMouseout);
}
init();
diff --git a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.min.js b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.min.js
index c02cee7a..36fa5d8e 100644
--- a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.min.js
+++ b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.min.js
@@ -1 +1 @@
-function InputfieldRepeater($){var depthSize=50;var isAdminDefault=$("body").hasClass("AdminThemeDefault");var doubleClickTimer=null;var eventReloaded=function(event,source){if(typeof source!="undefined"){if(source=="InputfieldRepeaterItemEdit"||source=="InputfieldRepeaterItemAdd"){event.stopPropagation();var $r=$(this).find(".InputfieldRepeater");if($r.length)$r.each(function(){initRepeater($(this))});return}}initRepeater($(this))};var eventDeleteClick=function(e){var $this=$(this);var $header=$this.closest(".InputfieldHeader");var $item=$header.parent();if(isActionDisabled($this))return false;if($item.hasClass("InputfieldRepeaterNewItem")){var $numAddInput=$item.children(".InputfieldContent").children(".InputfieldRepeaterAddItem").children("input");$numAddInput.attr("value",parseInt($numAddInput.attr("value")-1));$item.remove()}else{var pageID=$item.attr("data-page");var $checkbox=$item.find("#delete_repeater"+pageID);if($checkbox.is(":checked")){$checkbox.prop("checked",false);$header.removeClass("ui-state-error").addClass("ui-state-default");$item.removeClass("InputfieldRepeaterDeletePending")}else{$checkbox.prop("checked",true);$header.removeClass("ui-state-default").addClass("ui-state-error");if(!$item.hasClass("InputfieldStateCollapsed")){$header.find(".toggle-icon").click()}$item.addClass("InputfieldRepeaterDeletePending");$item.closest(".Inputfield").addClass("InputfieldStateChanged")}$header.find(".InputfieldRepeaterItemControls").css("background-color",$header.css("background-color"))}checkMinMax($item.closest(".InputfieldRepeater"));e.stopPropagation()};var eventDeleteDblClick=function(){var $this=$(this);var $li=$(this).closest("li");var undelete=$li.hasClass("InputfieldRepeaterDeletePending");if(isActionDisabled($this))return false;function selectAll(){$li.parent().children("li").each(function(){var $item=$(this);var $trashLink=$item.children(".InputfieldHeader").find(".InputfieldRepeaterTrash");if($item.hasClass("InputfieldRepeaterDeletePending")){if(undelete)$trashLink.click()}else{if(!undelete)$trashLink.click()}})}if(undelete){selectAll()}else{ProcessWire.confirm(ProcessWire.config.InputfieldRepeater.labels.removeAll,selectAll)}};var eventCloneClick=function(){var $this=$(this);if(isActionDisabled($this))return false;var $item=$this.closest(".InputfieldRepeaterItem");ProcessWire.confirm(ProcessWire.config.InputfieldRepeater.labels.clone,function(){var itemID=$item.attr("data-page");var $addLink=$item.closest(".InputfieldRepeater").children(".InputfieldContent").children(".InputfieldRepeaterAddItem").find(".InputfieldRepeaterAddLink:eq(0)");$addLink.attr("data-clone",itemID).click();$("html, body").animate({scrollTop:$addLink.offset().top-100},250,"swing")});return false};var eventSettingsClick=function(e){var $this=$(this);var $item=$this.closest(".InputfieldRepeaterItem");var $settingsParent=$item.children(".InputfieldContent").children(".Inputfields");var $settings=$settingsParent.children(".InputfieldRepeaterSettings");if(!$settings.length){$settingsParent=$settingsParent.children(".InputfieldWrapper").children(".Inputfields");$settings=$settingsParent.children(".InputfieldRepeaterSettings")}if($item.hasClass("InputfieldStateCollapsed")){$this.closest(".InputfieldHeader").click()}if($settings.is(":visible")){$settings.slideUp("fast");$this.addClass("ui-priority-secondary")}else{$settings.slideDown("fast");$this.removeClass("ui-priority-secondary")}return false};var eventToggleClick=function(e){var $this=$(this);var toggleOn=$this.attr("data-on");var toggleOff=$this.attr("data-off");var $item=$this.closest(".InputfieldRepeaterItem");var $input=$item.find(".InputfieldRepeaterPublish");if(doubleClickTimer)clearTimeout(doubleClickTimer);doubleClickTimer=setTimeout(function(){if(isActionDisabled($this))return false;if($this.hasClass(toggleOn)){$this.removeClass(toggleOn).addClass(toggleOff);$item.addClass("InputfieldRepeaterUnpublished InputfieldRepeaterOff");$input.val("-1")}else{$this.removeClass(toggleOff).addClass(toggleOn);$item.removeClass("InputfieldRepeaterUnpublished InputfieldRepeaterOff").addClass("InputfieldRepeaterWasUnpublished");$input.val("1")}checkMinMax($item.closest(".InputfieldRepeater"))},250);e.stopPropagation()};var eventItemOpenReady=function(){var $item=$(this);var $loaded=$item.find(".InputfieldRepeaterLoaded");if(parseInt($loaded.val())>0)return;$item.addClass("InputfieldRepeaterItemLoading")};var eventItemOpened=function(){var $item=$(this);var $loaded=$item.find(".InputfieldRepeaterLoaded");updateState($item);if(parseInt($loaded.val())>0){updateAccordion($item);return}$loaded.val("1");var $content=$item.find(".InputfieldContent").hide();var $repeater=$item.closest(".InputfieldRepeater");var pageID=$repeater.attr("data-page");var itemID=parseInt($item.attr("data-page"));var repeaterID=$repeater.attr("id");var fieldName=repeaterID.replace("wrap_Inputfield_","").replace("_LPID"+pageID,"");var ajaxURL=ProcessWire.config.InputfieldRepeater.editorUrl+"?id="+pageID+"&field="+fieldName+"&repeater_edit="+itemID;var $spinner=$item.find(".InputfieldRepeaterDrag");var $inputfields=$loaded.closest(".Inputfields");if($repeater.hasClass("InputfieldRenderValueMode"))ajaxURL+="&inrvm=1";if($repeater.hasClass("InputfieldNoDraft"))ajaxURL+="&nodraft=1";$spinner.removeClass("fa-arrows").addClass("fa-spin fa-spinner");repeaterID=repeaterID.replace(/_repeater\d+$/,"").replace("_LPID"+pageID,"");$.get(ajaxURL,function(data){var $inputs=$(data).find("#"+repeaterID+" > "+".InputfieldContent > .Inputfields > "+".InputfieldRepeaterItem > .InputfieldContent > .Inputfields > .InputfieldWrapper > "+".Inputfields > .Inputfield");$inputfields.append($inputs);$item.removeClass("InputfieldRepeaterItemLoading");InputfieldsInit($inputfields);var $repeaters=$inputs.find(".InputfieldRepeater");if($repeaters.length){$repeaters.each(function(){initRepeater($(this))})}else{$item.find(".InputfieldRepeaterSettings").hide()}$content.slideDown("fast",function(){$spinner.removeClass("fa-spin fa-spinner").addClass("fa-arrows");updateAccordion($item)});setTimeout(function(){$inputfields.find(".Inputfield").trigger("reloaded",["InputfieldRepeaterItemEdit"])},50);runScripts(data)})};var eventItemClosed=function(){updateState($(this))};var eventAddLinkClick=function(){var $addLink=$(this);var $inputfields=$addLink.parent("p").prev("ul.Inputfields");var $inputfieldRepeater=$addLink.closest(".InputfieldRepeater");var $numAddInput=$addLink.parent().children("input");var newItemTotal=0;var useAjax=$addLink.attr("data-noajax").length==0;var cloneID=$addLink.attr("data-clone");function addRepeaterItem($addItem){var id=$addItem.attr("id")+"_";while($("#"+id).length>0)id+="_";$addItem.attr("id",id);$inputfields.append($addItem);$addItem.css("display","block");adjustItemLabel($addItem,true);$addLink.trigger("repeateradd",[$addItem])}if(typeof cloneID=="undefined"||!cloneID)cloneID=null;if(cloneID)$addLink.removeAttr("data-clone");if(!useAjax){var $newItem=$inputfields.children(".InputfieldRepeaterNewItem");newItemTotal=$newItem.length;if(newItemTotal>0){if(newItemTotal>1)$newItem=$newItem.slice(0,1);var $addItem=$newItem.clone(true);addRepeaterItem($addItem);$numAddInput.attr("value",newItemTotal);checkMinMax($inputfieldRepeater)}return false}var pageID=$inputfieldRepeater.attr("data-page");var fieldName=$inputfieldRepeater.attr("id").replace("wrap_Inputfield_","");var $spinner=$addLink.parent().find(".InputfieldRepeaterSpinner");var ajaxURL=ProcessWire.config.InputfieldRepeater.editorUrl+"?id="+pageID+"&field="+fieldName;$spinner.removeClass($spinner.attr("data-off")).addClass($spinner.attr("data-on"));if(cloneID){ajaxURL+="&repeater_clone="+cloneID}else{ajaxURL+="&repeater_add="+$addLink.attr("data-type")}var $existingItems=$inputfields.find(".InputfieldRepeaterItem:not(.InputfieldRepeaterNewItem)");if($existingItems.length){ajaxURL+="&repeater_not=";$existingItems.each(function(){ajaxURL+=$(this).attr("data-page")+","})}$.get(ajaxURL,function(data){$spinner.removeClass($spinner.attr("data-on")).addClass($spinner.attr("data-off"));var $addItem=$(data).find(".InputfieldRepeaterItemRequested");if(!$addItem.length){return}addRepeaterItem($addItem);$addItem.wrap("
");InputfieldsInit($addItem.parent());initRepeater($addItem);$addItem.unwrap();$addItem.find(".Inputfield").trigger("reloaded",["InputfieldRepeaterItemAdd"]);if(cloneID){$addItem.find(".Inputfield").trigger("cloned",["InputfieldRepeaterItemAdd"]);$addItem.find(".InputfieldTableRowID").val(0)}$addItem.find(".InputfieldRepeaterSort").val($inputfields.children().length);$("html, body").animate({scrollTop:$addItem.offset().top},500,"swing");updateState($addItem);checkMinMax($inputfieldRepeater);updateAccordion($addItem);var $nestedRepeaters=$addItem.find(".InputfieldRepeater");if($nestedRepeaters.length){$nestedRepeaters.each(function(){initRepeater($(this))})}runScripts(data)});return false};var eventOpenAllClick=function(e){e.stopPropagation();e.preventDefault();if(doubleClickTimer)clearTimeout(doubleClickTimer);if($(this).closest(".InputfieldRepeater").hasClass("InputfieldRepeaterAccordion"))return false;var $repeater=$(this).closest(".InputfieldRepeater");var $items=$repeater.children(".InputfieldContent").children(".Inputfields").children(".InputfieldRepeaterItem");if(!$items.length)return false;var $item=$items.eq(0);var label,selector;if($item.hasClass("InputfieldStateCollapsed")){label=ProcessWire.config.InputfieldRepeater.labels.openAll;selector=".InputfieldStateCollapsed"}else{label=ProcessWire.config.InputfieldRepeater.labels.collapseAll;selector=".InputfieldRepeaterItem:not(.InputfieldStateCollapsed)"}ProcessWire.confirm(label,function(){$items.filter(selector).each(function(){$(this).children(".InputfieldHeader").find(".toggle-icon").click()})});return false};function isActionDisabled($this){if($this.hasClass("pw-icon-disabled")){ProcessWire.alert(ProcessWire.config.InputfieldRepeater.labels.disabledMinMax);return true}return false}function updateAccordion($item){if(!$item.closest(".InputfieldRepeater").hasClass("InputfieldRepeaterAccordion"))return false;var itemID=$item.attr("id");var useScroll=false;var $siblings=$item.parent().children(".InputfieldRepeaterItem");var itemHasPassed=false;var hasOpen=false;$siblings.each(function(){var $sibling=$(this);if($sibling.attr("id")==itemID){itemHasPassed=true;return}if($sibling.hasClass("InputfieldStateCollapsed"))return;if(!$sibling.is(":visible"))return;if(!itemHasPassed)useScroll=true;$sibling.children(".InputfieldHeader").find(".toggle-icon").trigger("click",[{duration:0}]);hasOpen=true});if(useScroll&&hasOpen){$("html, body").animate({scrollTop:$item.offset().top-10},0)}return true}function adjustItemLabel($item,doIncrement){var $label;$label=$item.children(".InputfieldHeader").find(".InputfieldRepeaterItemLabel");if(typeof $label=="undefined")$label=$item.children("label");var labelHTML=$label.html();var _labelHTML=labelHTML;if(typeof labelHTML!="undefined"){if(doIncrement&&labelHTML.indexOf("#")>-1){var num=$item.siblings(".InputfieldRepeaterItem:visible").length+1;labelHTML=labelHTML.replace(/#[0-9]+/,"#"+num)}while(labelHTML.indexOf("}")>-1){labelHTML=labelHTML.replace(/\{/,'');labelHTML=labelHTML.replace(/}/,"")}if(labelHTML!=_labelHTML){$label.html(labelHTML)}}}function sortableDepth(ui,maxDepth,updateNow){var $wrap=ui.item.children(".InputfieldContent").children(".Inputfields").children(".InputfieldRepeaterItemDepth");var $depth=$wrap.find("input");var depth=-1;var prevDepth=parseInt($depth.val());var left=ui.position.left;if(left<0){depth=prevDepth-Math.round(Math.abs(left)/depthSize)}else{depth=Math.round(left/depthSize)+prevDepth}if(updateNow){depth=setItemDepth(ui.item,depth,maxDepth);ui.item.children(".InputfieldHeader").removeClass("ui-state-error")}return depth}function setItemDepth($item,depth,maxDepth,noValidate){noValidate=typeof noValidate==="undefined"?false:noValidate;if(depth<1)depth=0;if(typeof maxDepth!=="undefined"&&depth>maxDepth)depth=maxDepth;if(!$item.hasClass("InputfieldRepeaterItem"))$item=$item.closest(".InputfieldRepeaterItem");if(!$item.length)return-1;var $depthInput=$item.children(".InputfieldContent").children(".Inputfields").children(".InputfieldRepeaterItemDepth").find("input");if(!$depthInput.length){console.log("Cannot find depth input for "+$item.attr("id"))}if(!noValidate&&$item.closest(".InputfieldRepeater").hasClass("InputfieldRepeaterFamilyFriendly")){var $prevItem=$item.prev(".InputfieldRepeaterItem:not(.InputfieldRepeaterNewItem)");if($prevItem.length){var prevItemDepth=parseInt($prevItem.attr("data-depth"));if(depth-prevItemDepth>1)depth=prevItemDepth+1}else{depth=0}}$depthInput.val(depth);$item.attr("data-depth",depth);if(depth>0){$item.css("margin-left",depth*depthSize+"px")}else{$item.css("margin-left",0)}return depth}function getItemDepth($item){if(!$item.hasClass("InputfieldRepeaterItem"))$item=$item.closest(".InputfieldRepeaterItem");if(!$item.length)return-1;return parseInt($item.attr("data-depth"))}function getDepthChildren($item){var children=[];var n=0;var startDepth=parseInt($item.attr("data-depth"));var pageId=$item.attr("data-page");var pageIdClass="Inputfield_repeater_item_"+pageId;while($item.hasClass(pageIdClass)){var $nextItem=$item.next(".InputfieldRepeaterItem:not(.InputfieldRepeaterNewItem)");if(!$nextItem.length||!$nextItem.hasClass(pageIdClass))break;$item=$nextItem}do{var $child=$item.next(".InputfieldRepeaterItem:not(.InputfieldRepeaterNewItem)");if(!$child.length)break;var childDepth=parseInt($child.attr("data-depth"));if(!childDepth||childDepth<=startDepth)break;$item=$child;children[n]=$child;n++}while(true);return children}function initDepths($inputfieldRepeater){$inputfieldRepeater.find(".InputfieldRepeaterItemDepth").each(function(){var $wrap=$(this);var $depth=$wrap.find("input");var depth=$depth.val();var $item=$depth.closest(".InputfieldRepeaterItem");var currentLeft=$item.css("margin-left");if(currentLeft=="auto")currentLeft=0;currentLeft=parseInt(currentLeft);var targetLeft=depth*depthSize;if(targetLeft!=currentLeft){$item.css("margin-left",targetLeft+"px")}});$inputfieldRepeater.children(".InputfieldContent").css("position","relative")}function initSortable($inputfieldRepeater,$inputfields){var maxDepth=parseInt($inputfieldRepeater.attr("data-depth"));var depthChildren=[];var startDepth=0;var familyFriendly=$inputfieldRepeater.hasClass("InputfieldRepeaterFamilyFriendly");var sortableOptions={items:"> li:not(.InputfieldRepeaterNewItem)",handle:".InputfieldRepeaterDrag",start:function(e,ui){ui.item.find(".InputfieldHeader").addClass("ui-state-highlight");ui.item.find("textarea.InputfieldCKEditorNormal.InputfieldCKEditorLoaded").each(function(){$(this).removeClass("InputfieldCKEditorLoaded");var editor=CKEDITOR.instances[$(this).attr("id")];editor.destroy();CKEDITOR.remove($(this).attr("id"))});ui.item.find(".InputfieldTinyMCE textarea").each(function(){tinyMCE.execCommand("mceRemoveControl",false,$(this).attr("id"))});if(familyFriendly&&maxDepth>0){startDepth=parseInt(ui.item.attr("data-depth"));depthChildren=getDepthChildren(ui.item);for(var n=0;n0){sortableDepth(ui,maxDepth,true)}if(maxDepth>0&&familyFriendly&&depthChildren.length){var $item=ui.item;var stopDepth=parseInt($item.attr("data-depth"));var diffDepth=stopDepth-startDepth;for(var n=0;n0){initDepths($inputfieldRepeater);sortableOptions.grid=[depthSize,1];sortableOptions.sort=function(event,ui){var depth=sortableDepth(ui,99,false);var $header=ui.item.children(".InputfieldHeader");if(depth>maxDepth){$header.addClass("ui-state-error")}else if($header.hasClass("ui-state-error")){$header.removeClass("ui-state-error")}}}else{sortableOptions.axis="y"}$(".InputfieldRepeaterDrag",$inputfields).hover(function(){$(this).parent("label").addClass("ui-state-focus")},function(){$(this).parent("label").removeClass("ui-state-focus")});$inputfields.sortable(sortableOptions)}function initHeaders($headers,$inputfieldRepeater,renderValueMode){var $clone=$("").css("display","block");var $delete=$("");var $toggle=$("");var cfg=ProcessWire.config.InputfieldRepeater;var allowClone=!$inputfieldRepeater.hasClass("InputfieldRepeaterNoAjaxAdd");var allowSettings=$inputfieldRepeater.hasClass("InputfieldRepeaterHasSettings");if(cfg){$toggle.attr("title",cfg.labels.toggle);$delete.attr("title",cfg.labels.remove);$clone.attr("title",cfg.labels.clone)}if(allowSettings){$inputfieldRepeater.find(".InputfieldRepeaterSettings").hide()}$headers.each(function(){var $t=$(this);if($t.hasClass("InputfieldRepeaterHeaderInit"))return;var icon="fa-arrows";var $item=$t.parent();if($item.hasClass("InputfieldRepeaterNewItem")){icon="fa-plus";$t.addClass("ui-priority-secondary")}$t.addClass("ui-state-default InputfieldRepeaterHeaderInit");$t.prepend("");if(!renderValueMode){var $controls=$("");var $toggleControl=$toggle.clone(true).addClass($t.parent().hasClass("InputfieldRepeaterOff")?"fa-toggle-off":"fa-toggle-on");var $deleteControl=$delete.clone(true);var $collapseControl=$t.find(".toggle-icon");$controls.prepend($collapseControl);if($t.closest(".InputfieldRepeater").hasClass("InputfieldRepeaterHasSettings")){var $settingsToggle=$("").attr("title",cfg.labels.settings);$controls.prepend($settingsToggle)}if(allowClone)$controls.prepend($clone.clone(true));$controls.prepend($toggleControl);$controls.prepend($deleteControl);$t.prepend($controls);$controls.css("background-color",$t.css("background-color"))}adjustItemLabel($item,false)})}function initRepeater($this){var $inputfields,$inputfieldRepeater,isItem;if($this.hasClass("InputfieldRepeaterItem")){$inputfields=$this;$inputfieldRepeater=$this.closest(".InputfieldRepeater");isItem=true}else{$inputfields=$this.find(".Inputfields:eq(0)");$inputfieldRepeater=$this;isItem=false}if($inputfields.hasClass("InputfieldRepeaterInit"))return;var renderValueMode=$inputfields.closest(".InputfieldRenderValueMode").length>0;$inputfields.addClass("InputfieldRepeaterInit");if(isItem){initHeaders($this.children(".InputfieldHeader"),$inputfieldRepeater,renderValueMode)}else{initHeaders($(".InputfieldRepeaterItem > .InputfieldHeader",$this),$inputfieldRepeater,renderValueMode)}if(renderValueMode){initDepths($inputfieldRepeater);return}$(".InputfieldRepeaterTrash",$this).hover(function(){var $label=$(this).closest("label");if(!$label.parents().hasClass("InputfieldRepeaterDeletePending"))$label.addClass("ui-state-error");$label.find(".InputfieldRepeaterItemControls").css("background-color",$label.css("background-color"))},function(){var $label=$(this).closest("label");if(!$label.parent().hasClass("InputfieldRepeaterDeletePending"))$label.removeClass("ui-state-error");$label.find(".InputfieldRepeaterItemControls").css("background-color",$label.css("background-color"))});if(isItem)$inputfields=$inputfieldRepeater.find(".Inputfields:eq(0)");initSortable($inputfieldRepeater,$inputfields);$(".InputfieldRepeaterAddLink:not(.InputfieldRepeaterAddLinkInit)",$inputfieldRepeater).addClass("InputfieldRepeaterAddLinkInit").click(eventAddLinkClick);if($inputfieldRepeater.hasClass("InputfieldRepeaterMax")){checkMinMax($inputfieldRepeater)}}function checkMinMax($inputfieldRepeater){if(!$inputfieldRepeater.hasClass("InputfieldRepeaterMax")&&!$inputfieldRepeater.hasClass("InputfieldRepeaterMin"))return;var max=parseInt($inputfieldRepeater.attr("data-max"));var min=parseInt($inputfieldRepeater.attr("data-min"));if(max<=0&&min<=0)return;var $content=$inputfieldRepeater.children(".InputfieldContent");var num=$content.children(".Inputfields").children("li:not(.InputfieldRepeaterDeletePending):not(.InputfieldRepeaterOff):visible").length;var $addItem=$content.children(".InputfieldRepeaterAddItem");var cloneChange="";var trashChange="";if(max>0){if(num>=max){$addItem.hide();cloneChange="hide"}else if(!$addItem.is(":visible")){$addItem.show();cloneChange="show"}}if(min>0){if(num<=min){trashChange="hide";$content.addClass("InputfieldRepeaterTrashHidden")}else if($content.hasClass("InputfieldRepeaterTrashHidden")){$content.removeClass("InputfieldRepeaterTrashHidden");trashChange="show"}}if(cloneChange.length||trashChange.length){var $items=$content.children(".Inputfields").children(".InputfieldRepeaterItem");if(cloneChange.length){$items.each(function(){var $clone=$(this).children(".InputfieldHeader").find(".InputfieldRepeaterClone");if(cloneChange==="show"){$clone.removeClass("pw-icon-disabled")}else{$clone.addClass("pw-icon-disabled")}})}if(trashChange.length){$items.each(function(){var $header=$(this).children(".InputfieldHeader");var $trash=$header.find(".InputfieldRepeaterTrash");var $toggle=$header.find(".InputfieldRepeaterToggle.fa-toggle-on");if(trashChange==="show"){$trash.removeClass("pw-icon-disabled");$toggle.removeClass("pw-icon-disabled")}else{$trash.addClass("pw-icon-disabled");$toggle.addClass("pw-icon-disabled")}});if(trashChange=="hide"){$content.children(".Inputfields").children("li.InputfieldRepeaterDeletePending").each(function(){var $trash=$(this).children(".InputfieldHeader").find(".InputfieldRepeaterTrash");$trash.removeClass("pw-icon-disabled")})}}}}function runScripts(data){if(data.indexOf("<\/script>")==-1)return;var d=document.createElement("div");d.innerHTML=data;var scripts=d.querySelectorAll(".Inputfield script");$(scripts).each(function(){$.globalEval(this.text||this.textContent||this.innerHTML||"")})}function updateState($item){if($item.closest(".InputfieldRepeaterRememberOpen").length<1)return;var val="";$(".InputfieldRepeaterItem:not(.InputfieldStateCollapsed)").each(function(){var id=parseInt($(this).attr("data-page"));if(id>0){val+=id+"|"}});$.cookie("repeaters_open",val)}function init(){$(".InputfieldRepeater").each(function(){initRepeater($(this))});$(document).on("reloaded",".InputfieldRepeater",eventReloaded).on("click",".InputfieldRepeaterTrash",eventDeleteClick).on("dblclick",".InputfieldRepeaterTrash",eventDeleteDblClick).on("click",".InputfieldRepeaterClone",eventCloneClick).on("click",".InputfieldRepeaterSettingsToggle",eventSettingsClick).on("dblclick",".InputfieldRepeaterToggle",eventOpenAllClick).on("click",".InputfieldRepeaterToggle",eventToggleClick).on("opened",".InputfieldRepeaterItem",eventItemOpened).on("closed",".InputfieldRepeaterItem",eventItemClosed).on("openReady",".InputfieldRepeaterItem",eventItemOpenReady)}init()}jQuery(document).ready(function($){InputfieldRepeater($)});
\ No newline at end of file
+function InputfieldRepeater($){var depthSize=50;var isAdminDefault=$("body").hasClass("AdminThemeDefault");var doubleClickTimer=null;var currentlyAddingItem=false;var insertTimeout=null;var eventReloaded=function(event,source){if(typeof source!="undefined"){if(source=="InputfieldRepeaterItemEdit"||source=="InputfieldRepeaterItemAdd"){event.stopPropagation();var $r=$(this).find(".InputfieldRepeater");if($r.length)$r.each(function(){initRepeater($(this))});return}}initRepeater($(this))};var eventDeleteClick=function(e){var $this=$(this);var $header=$this.closest(".InputfieldHeader");var $item=$header.parent();if(isActionDisabled($this))return false;if($item.hasClass("InputfieldRepeaterNewItem")){var $numAddInput=$item.children(".InputfieldContent").children(".InputfieldRepeaterAddItem").children("input");$numAddInput.attr("value",parseInt($numAddInput.attr("value")-1));$item.remove()}else{var pageID=$item.attr("data-page");var $checkbox=$item.find("#delete_repeater"+pageID);if($checkbox.is(":checked")){$checkbox.prop("checked",false);$header.removeClass("ui-state-error").addClass("ui-state-default");$item.removeClass("InputfieldRepeaterDeletePending")}else{$checkbox.prop("checked",true);$header.removeClass("ui-state-default").addClass("ui-state-error");if(!$item.hasClass("InputfieldStateCollapsed")){$header.find(".toggle-icon").click()}$item.addClass("InputfieldRepeaterDeletePending");$item.closest(".Inputfield").addClass("InputfieldStateChanged")}$header.find(".InputfieldRepeaterItemControls").css("background-color",$header.css("background-color"))}checkMinMax($item.closest(".InputfieldRepeater"));e.stopPropagation()};var eventDeleteDblClick=function(){var $this=$(this);var $li=$(this).closest("li");var undelete=$li.hasClass("InputfieldRepeaterDeletePending");if(isActionDisabled($this))return false;function selectAll(){$li.parent().children("li").each(function(){var $item=$(this);var $trashLink=$item.children(".InputfieldHeader").find(".InputfieldRepeaterTrash");if($item.hasClass("InputfieldRepeaterDeletePending")){if(undelete)$trashLink.click()}else{if(!undelete)$trashLink.click()}})}if(undelete){selectAll()}else{ProcessWire.confirm(ProcessWire.config.InputfieldRepeater.labels.removeAll,selectAll)}};var eventCloneClick=function(){var $this=$(this);if(isActionDisabled($this))return false;var $item=$this.closest(".InputfieldRepeaterItem");ProcessWire.confirm(ProcessWire.config.InputfieldRepeater.labels.clone,function(){var itemID=$item.attr("data-page");var $addLink=$item.closest(".InputfieldRepeater").children(".InputfieldContent").children(".InputfieldRepeaterAddItem").find(".InputfieldRepeaterAddLink:eq(0)");$addLink.attr("data-clone",itemID).click();$("html, body").animate({scrollTop:$addLink.offset().top-100},250,"swing")});return false};var eventSettingsClick=function(e){var $this=$(this);var $item=$this.closest(".InputfieldRepeaterItem");var $settingsParent=$item.children(".InputfieldContent").children(".Inputfields");var $settings=$settingsParent.children(".InputfieldRepeaterSettings");if(!$settings.length){$settingsParent=$settingsParent.children(".InputfieldWrapper").children(".Inputfields");$settings=$settingsParent.children(".InputfieldRepeaterSettings")}if($item.hasClass("InputfieldStateCollapsed")){$this.closest(".InputfieldHeader").click()}if($settings.is(":visible")){$settings.slideUp("fast");$this.addClass("ui-priority-secondary")}else{$settings.slideDown("fast");$this.removeClass("ui-priority-secondary")}return false};var eventToggleClick=function(e){var $this=$(this);var toggleOn=$this.attr("data-on");var toggleOff=$this.attr("data-off");var $item=$this.closest(".InputfieldRepeaterItem");var $input=$item.find(".InputfieldRepeaterPublish");if(doubleClickTimer)clearTimeout(doubleClickTimer);doubleClickTimer=setTimeout(function(){if(isActionDisabled($this))return false;if($this.hasClass(toggleOn)){$this.removeClass(toggleOn).addClass(toggleOff);$item.addClass("InputfieldRepeaterUnpublished InputfieldRepeaterOff");$input.val("-1")}else{$this.removeClass(toggleOff).addClass(toggleOn);$item.removeClass("InputfieldRepeaterUnpublished InputfieldRepeaterOff").addClass("InputfieldRepeaterWasUnpublished");$input.val("1")}checkMinMax($item.closest(".InputfieldRepeater"))},250);e.stopPropagation()};var eventItemOpenReady=function(){var $item=$(this);var $loaded=$item.find(".InputfieldRepeaterLoaded");if(parseInt($loaded.val())>0)return;$item.addClass("InputfieldRepeaterItemLoading")};var eventItemOpened=function(){var $item=$(this);var $loaded=$item.find(".InputfieldRepeaterLoaded");updateState($item);if(parseInt($loaded.val())>0){updateAccordion($item);return}$loaded.val("1");var $content=$item.find(".InputfieldContent").hide();var $repeater=$item.closest(".InputfieldRepeater");var pageID=$repeater.attr("data-page");var itemID=parseInt($item.attr("data-page"));var repeaterID=$repeater.attr("id");var fieldName=repeaterID.replace("wrap_Inputfield_","").replace("_LPID"+pageID,"");var ajaxURL=ProcessWire.config.InputfieldRepeater.editorUrl+"?id="+pageID+"&field="+fieldName+"&repeater_edit="+itemID;var $spinner=$item.find(".InputfieldRepeaterDrag");var $inputfields=$loaded.closest(".Inputfields");if($repeater.hasClass("InputfieldRenderValueMode"))ajaxURL+="&inrvm=1";if($repeater.hasClass("InputfieldNoDraft"))ajaxURL+="&nodraft=1";$spinner.removeClass("fa-arrows").addClass("fa-spin fa-spinner");repeaterID=repeaterID.replace(/_repeater\d+$/,"").replace("_LPID"+pageID,"");$.get(ajaxURL,function(data){var $inputs=$(data).find("#"+repeaterID+" > "+".InputfieldContent > .Inputfields > "+".InputfieldRepeaterItem > .InputfieldContent > .Inputfields > .InputfieldWrapper > "+".Inputfields > .Inputfield");$inputfields.append($inputs);$item.removeClass("InputfieldRepeaterItemLoading");InputfieldsInit($inputfields);var $repeaters=$inputs.find(".InputfieldRepeater");if($repeaters.length){$repeaters.each(function(){initRepeater($(this))})}else{$item.find(".InputfieldRepeaterSettings").hide()}$content.slideDown("fast",function(){$spinner.removeClass("fa-spin fa-spinner").addClass("fa-arrows");updateAccordion($item)});setTimeout(function(){$inputfields.find(".Inputfield").trigger("reloaded",["InputfieldRepeaterItemEdit"])},50);runScripts(data)})};var eventItemClosed=function(){updateState($(this))};var eventAddLinkClick=function(){currentlyAddingItem=true;var $addLink=$(this);var $inputfields=$addLink.parent("p").prev("ul.Inputfields");var $inputfieldRepeater=$addLink.closest(".InputfieldRepeater");var $numAddInput=$addLink.parent().children("input");var newItemTotal=0;var useAjax=$addLink.attr("data-noajax").length==0;var cloneID=$addLink.attr("data-clone");var depth=0;var redoSortAll=false;function addRepeaterItem($addItem){var id=$addItem.attr("id")+"_";while($("#"+id).length>0)id+="_";$addItem.attr("id",id);var $insertItem=$inputfields.children(".InputfieldRepeaterInsertItem");if($insertItem.length){depth=getItemDepth($insertItem);$addItem.addClass("InputfieldStateCollapsed");var $toggleIcon=$addItem.children(".InputfieldHeader").find(".toggle-icon");$toggleIcon.toggleClass($toggleIcon.attr("data-to"));$insertItem.replaceWith($addItem);redoSortAll=true}else{$inputfields.append($addItem)}$addItem.css("display","block");adjustItemLabel($addItem,true);$addLink.trigger("repeateradd",[$addItem])}if(typeof cloneID=="undefined"||!cloneID)cloneID=null;if(cloneID)$addLink.removeAttr("data-clone");if(!useAjax){var $newItem=$inputfields.children(".InputfieldRepeaterNewItem");newItemTotal=$newItem.length;if(newItemTotal>0){if(newItemTotal>1)$newItem=$newItem.slice(0,1);var $addItem=$newItem.clone(true);if(depth)setItemDepth($addItem,depth);addRepeaterItem($addItem);$numAddInput.attr("value",newItemTotal);checkMinMax($inputfieldRepeater)}currentlyAddingItem=false;return false}var pageID=$inputfieldRepeater.attr("data-page");var fieldName=$inputfieldRepeater.attr("id").replace("wrap_Inputfield_","");var $spinner=$addLink.parent().find(".InputfieldRepeaterSpinner");var ajaxURL=ProcessWire.config.InputfieldRepeater.editorUrl+"?id="+pageID+"&field="+fieldName;$spinner.removeClass($spinner.attr("data-off")).addClass($spinner.attr("data-on"));if(cloneID){ajaxURL+="&repeater_clone="+cloneID}else{ajaxURL+="&repeater_add="+$addLink.attr("data-type")}var $existingItems=$inputfields.find(".InputfieldRepeaterItem:not(.InputfieldRepeaterNewItem)");if($existingItems.length){ajaxURL+="&repeater_not=";$existingItems.each(function(){ajaxURL+=$(this).attr("data-page")+","})}$.get(ajaxURL,function(data){$spinner.removeClass($spinner.attr("data-on")).addClass($spinner.attr("data-off"));var $addItem=$(data).find(".InputfieldRepeaterItemRequested");if(!$addItem.length){return}addRepeaterItem($addItem);$addItem.wrap("");InputfieldsInit($addItem.parent());initRepeater($addItem);$addItem.unwrap();$addItem.find(".Inputfield").trigger("reloaded",["InputfieldRepeaterItemAdd"]);if(cloneID){$addItem.find(".Inputfield").trigger("cloned",["InputfieldRepeaterItemAdd"]);$addItem.find(".InputfieldTableRowID").val(0)}if(redoSortAll){$inputfields.children(".InputfieldRepeaterItem").each(function(n){setItemSort($(this),n)})}else{setItemSort($addItem,$inputfields.children().length)}if(depth)setItemDepth($addItem,depth);if($addItem.hasClass("InputfieldStateCollapsed")){}else{$("html, body").animate({scrollTop:$addItem.offset().top},500,"swing")}updateState($addItem);checkMinMax($inputfieldRepeater);updateAccordion($addItem);var $nestedRepeaters=$addItem.find(".InputfieldRepeater");if($nestedRepeaters.length){$nestedRepeaters.each(function(){initRepeater($(this))})}runScripts(data);setTimeout(function(){currentlyAddingItem=false},500)});return false};var eventOpenAllClick=function(e){e.stopPropagation();e.preventDefault();if(doubleClickTimer)clearTimeout(doubleClickTimer);if($(this).closest(".InputfieldRepeater").hasClass("InputfieldRepeaterAccordion"))return false;var $repeater=$(this).closest(".InputfieldRepeater");var $items=$repeater.children(".InputfieldContent").children(".Inputfields").children(".InputfieldRepeaterItem");if(!$items.length)return false;var $item=$items.eq(0);var label,selector;if($item.hasClass("InputfieldStateCollapsed")){label=ProcessWire.config.InputfieldRepeater.labels.openAll;selector=".InputfieldStateCollapsed"}else{label=ProcessWire.config.InputfieldRepeater.labels.collapseAll;selector=".InputfieldRepeaterItem:not(.InputfieldStateCollapsed)"}ProcessWire.confirm(label,function(){$items.filter(selector).each(function(){$(this).children(".InputfieldHeader").find(".toggle-icon").click()})});return false};var eventInsertBeforeClick=function(e){var $item=$(this).closest(".InputfieldRepeaterItem");eventInsertClick($item,true);e.stopPropagation()};var eventInsertAfterClick=function(e){var $item=$(this).closest(".InputfieldRepeaterItem");eventInsertClick($item,false);e.stopPropagation()};function eventInsertClick($item,insertBefore){if(currentlyAddingItem)return false;currentlyAddingItem=true;if(insertTimeout)clearTimeout(insertTimeout);var depth=getInsertItemDepth($item,insertBefore);var $insertItem=$item.siblings(".InputfieldRepeaterInsertItem");if($insertItem.length){$insertItem.remove()}var $placeholder=$item.siblings(".InputfieldRepeaterNewItem").clone().removeClass(".InputfieldRepeaterNewItem").addClass("InputfieldRepeaterInsertItem");$placeholder.attr("id",$placeholder.attr("id")+"-placeholder");$placeholder.find(".InputfieldHeader").html("");if(insertBefore){$placeholder.insertBefore($item)}else{$placeholder.insertAfter($item)}if(depth>0)setItemDepth($placeholder,depth);$placeholder.show();if(!insertBefore&&!$item.hasClass("InputfieldStateCollapsed"))scrollToItem($placeholder);$placeholder.children(".InputfieldHeader").effect("highlight",{},500);$item.parent(".Inputfields").siblings(".InputfieldRepeaterAddItem").find(".InputfieldRepeaterAddLink:eq(0)").click()}var eventInsertMouseout=function(e){if(currentlyAddingItem)return;if(insertTimeout)clearTimeout(insertTimeout);var $action=$(this);var $newItem=$action.data("newItem");$action.removeClass("hov");if($newItem&&$newItem.length){if($newItem.hasClass("hov"))return;$newItem.remove()}};var eventInsertMouseover=function(e){if(currentlyAddingItem)return;if(insertTimeout)clearTimeout(insertTimeout);var $action=$(this);var insertBefore=$action.hasClass("InputfieldRepeaterInsertBefore");var $item=$(this).closest(".InputfieldRepeaterItem");var depth=0;$item.siblings(".InputfieldRepeaterInsertItem").remove();var $newItem=$item.siblings(".InputfieldRepeaterNewItem").clone();$newItem.addClass("InputfieldRepeaterInsertItem").attr("id",$newItem.attr("id")+"-insert");if(insertBefore){depth=getInsertBeforeItemDepth($item);$newItem.addClass("InputfieldRepeaterInsertItemBefore")}else{depth=getInsertAfterItemDepth($item);$newItem.addClass("InputfieldRepeaterInsertItemAfter")}$newItem.find(".InputfieldRepeaterItemControls").hide();$newItem.find(".InputfieldRepeaterItemLabel").text(ProcessWire.config.InputfieldRepeater.labels.insertHere);$action.addClass("hov").data("newItem",$newItem);setItemDepth($newItem,depth);insertTimeout=setTimeout(function(){insertTimeout=null;if(!$action.hasClass("hov")){$newItem.remove();return}else if(insertBefore){$newItem.insertBefore($item)}else{$newItem.addClass("hov").insertAfter($item)}$newItem.on("mouseover",function(){$(this).addClass("hov")}).on("click",function(e){e.stopPropagation();eventInsertClick($item,insertBefore)}).on("mouseout",function(){$(this).removeClass("hov").remove()});$newItem.slideDown()},1e3)};function isActionDisabled($this){if($this.hasClass("pw-icon-disabled")){ProcessWire.alert(ProcessWire.config.InputfieldRepeater.labels.disabledMinMax);return true}return false}function updateAccordion($item){if(!$item.closest(".InputfieldRepeater").hasClass("InputfieldRepeaterAccordion"))return false;var itemID=$item.attr("id");var useScroll=false;var $siblings=$item.parent().children(".InputfieldRepeaterItem");var itemHasPassed=false;var hasOpen=false;$siblings.each(function(){var $sibling=$(this);if($sibling.attr("id")==itemID){itemHasPassed=true;return}if($sibling.hasClass("InputfieldStateCollapsed"))return;if(!$sibling.is(":visible"))return;if(!itemHasPassed)useScroll=true;$sibling.children(".InputfieldHeader").find(".toggle-icon").trigger("click",[{duration:0}]);hasOpen=true});if(useScroll&&hasOpen){scrollToItem($item)}return true}function adjustItemLabel($item,doIncrement){var $label;$label=$item.children(".InputfieldHeader").find(".InputfieldRepeaterItemLabel");if(typeof $label=="undefined")$label=$item.children("label");var labelHTML=$label.html();var _labelHTML=labelHTML;if(typeof labelHTML!="undefined"){if(doIncrement&&labelHTML.indexOf("#")>-1){var num=$item.siblings(".InputfieldRepeaterItem:visible").length+1;labelHTML=labelHTML.replace(/#[0-9]+/,"#"+num)}while(labelHTML.indexOf("}")>-1){labelHTML=labelHTML.replace(/\{/,'');labelHTML=labelHTML.replace(/}/,"")}if(labelHTML!=_labelHTML){$label.html(labelHTML)}}}function setItemSort($item,sort){var $input=getItemSortInput($item);if($input.length)$input.val(sort)}function getItemSort($item){var $input=getItemSortInput($item);if($input.length)return parseInt($input.val());return-1}function getItemSortInput($item){if(!$item.hasClass("InputfieldRepeaterItem"))$item=$item.closest(".InputfieldRepeaterItem");return $item.children(".InputfieldContent").children(".Inputfields").children(".InputfieldRepeaterItemSort").find(".InputfieldRepeaterSort")}function sortableDepth(ui,maxDepth,updateNow){var $wrap=ui.item.children(".InputfieldContent").children(".Inputfields").children(".InputfieldRepeaterItemDepth");var $depth=$wrap.find("input");var depth=-1;var prevDepth=parseInt($depth.val());var left=ui.position.left;if(left<0){depth=prevDepth-Math.round(Math.abs(left)/depthSize)}else{depth=Math.round(left/depthSize)+prevDepth}if(updateNow){depth=setItemDepth(ui.item,depth,maxDepth);ui.item.children(".InputfieldHeader").removeClass("ui-state-error")}return depth}function setItemDepth($item,depth,maxDepth,noValidate){noValidate=typeof noValidate==="undefined"?false:noValidate;if(depth<1)depth=0;if(typeof maxDepth!=="undefined"&&depth>maxDepth)depth=maxDepth;if(!$item.hasClass("InputfieldRepeaterItem"))$item=$item.closest(".InputfieldRepeaterItem");if(!$item.length)return-1;var $depthInput=$item.children(".InputfieldContent").children(".Inputfields").children(".InputfieldRepeaterItemDepth").find("input");if(!$depthInput.length&&!$item.hasClass("InputfieldRepeaterNewItem")){console.log("Cannot find depth input for "+$item.attr("id"))}if(!noValidate&&$item.closest(".InputfieldRepeater").hasClass("InputfieldRepeaterFamilyFriendly")){var $prevItem=$item.prev(".InputfieldRepeaterItem:not(.InputfieldRepeaterNewItem)");if($prevItem.length){var prevItemDepth=parseInt($prevItem.attr("data-depth"));if(depth-prevItemDepth>1)depth=prevItemDepth+1}else{depth=0}}$depthInput.val(depth);$item.attr("data-depth",depth);if(depth>0){$item.css("margin-left",depth*depthSize+"px")}else{$item.css("margin-left",0)}return depth}function getItemDepth($item){if(!$item.hasClass("InputfieldRepeaterItem"))$item=$item.closest(".InputfieldRepeaterItem");if(!$item.length)return-1;return parseInt($item.attr("data-depth"))}function getInsertItemDepth($contextItem,insertBefore){var depth=0;if(insertBefore){depth=getItemDepth($contextItem)}else{var $nextItem=$contextItem.next(".InputfieldRepeaterItem");depth=getItemDepth($contextItem);if($nextItem.hasClass("InputfieldRepeaterNewItem")){if(!$nextItem.hasClass("InputfieldRepeaterInsertItem"))$nextItem=null}var nextDepth=$nextItem&&$nextItem.length?getItemDepth($nextItem):depth;if(nextDepth>depth)depth=nextDepth}return depth}function getInsertBeforeItemDepth($item){return getInsertItemDepth($item,true)}function getInsertAfterItemDepth($item){return getInsertItemDepth($item,false)}function getDepthChildren($item){var children=[];var n=0;var startDepth=parseInt($item.attr("data-depth"));var pageId=$item.attr("data-page");var pageIdClass="Inputfield_repeater_item_"+pageId;while($item.hasClass(pageIdClass)){var $nextItem=$item.next(".InputfieldRepeaterItem:not(.InputfieldRepeaterNewItem)");if(!$nextItem.length||!$nextItem.hasClass(pageIdClass))break;$item=$nextItem}do{var $child=$item.next(".InputfieldRepeaterItem:not(.InputfieldRepeaterNewItem)");if(!$child.length)break;var childDepth=parseInt($child.attr("data-depth"));if(!childDepth||childDepth<=startDepth)break;$item=$child;children[n]=$child;n++}while(true);return children}function initDepths($inputfieldRepeater){$inputfieldRepeater.find(".InputfieldRepeaterItemDepth").each(function(){var $wrap=$(this);var $depth=$wrap.find("input");var depth=$depth.val();var $item=$depth.closest(".InputfieldRepeaterItem");var currentLeft=$item.css("margin-left");if(currentLeft=="auto")currentLeft=0;currentLeft=parseInt(currentLeft);var targetLeft=depth*depthSize;if(targetLeft!=currentLeft){$item.css("margin-left",targetLeft+"px")}});$inputfieldRepeater.children(".InputfieldContent").css("position","relative")}function initSortable($inputfieldRepeater,$inputfields){var maxDepth=parseInt($inputfieldRepeater.attr("data-depth"));var depthChildren=[];var startDepth=0;var familyFriendly=$inputfieldRepeater.hasClass("InputfieldRepeaterFamilyFriendly");var sortableOptions={items:"> li:not(.InputfieldRepeaterNewItem)",handle:".InputfieldRepeaterDrag",start:function(e,ui){ui.item.find(".InputfieldHeader").addClass("ui-state-highlight");ui.item.find("textarea.InputfieldCKEditorNormal.InputfieldCKEditorLoaded").each(function(){$(this).removeClass("InputfieldCKEditorLoaded");var editor=CKEDITOR.instances[$(this).attr("id")];editor.destroy();CKEDITOR.remove($(this).attr("id"))});ui.item.find(".InputfieldTinyMCE textarea").each(function(){tinyMCE.execCommand("mceRemoveControl",false,$(this).attr("id"))});if(familyFriendly&&maxDepth>0){startDepth=parseInt(ui.item.attr("data-depth"));depthChildren=getDepthChildren(ui.item);for(var n=0;n0){sortableDepth(ui,maxDepth,true)}if(maxDepth>0&&familyFriendly&&depthChildren.length){var $item=ui.item;var stopDepth=parseInt($item.attr("data-depth"));var diffDepth=stopDepth-startDepth;for(var n=0;n0){initDepths($inputfieldRepeater);sortableOptions.grid=[depthSize,1];sortableOptions.sort=function(event,ui){var depth=sortableDepth(ui,99,false);var $header=ui.item.children(".InputfieldHeader");if(depth>maxDepth){$header.addClass("ui-state-error")}else if($header.hasClass("ui-state-error")){$header.removeClass("ui-state-error")}}}else{sortableOptions.axis="y"}$(".InputfieldRepeaterDrag",$inputfields).hover(function(){$(this).parent("label").addClass("ui-state-focus")},function(){$(this).parent("label").removeClass("ui-state-focus")});$inputfields.sortable(sortableOptions)}function initHeaders($headers,$inputfieldRepeater,renderValueMode){var $clone=$("").css("display","block");var $delete=$("");var $toggle=$("");var $insertAfter=$("");var $insertBefore=$("");var cfg=ProcessWire.config.InputfieldRepeater;var allowClone=!$inputfieldRepeater.hasClass("InputfieldRepeaterNoAjaxAdd");var allowSettings=$inputfieldRepeater.hasClass("InputfieldRepeaterHasSettings");if(cfg){$toggle.attr("title",cfg.labels.toggle);$delete.attr("title",cfg.labels.remove);$clone.attr("title",cfg.labels.clone);$insertBefore.attr("title",cfg.labels.insertBefore);$insertAfter.attr("title",cfg.labels.insertAfter)}if(allowSettings){$inputfieldRepeater.find(".InputfieldRepeaterSettings").hide()}$headers.each(function(){var $t=$(this);if($t.hasClass("InputfieldRepeaterHeaderInit"))return;var icon="fa-arrows";var $item=$t.parent();if($item.hasClass("InputfieldRepeaterNewItem")){icon="fa-plus-circle";$t.addClass("ui-priority-secondary")}$t.addClass("ui-state-default InputfieldRepeaterHeaderInit");$t.prepend("");if(!renderValueMode){var $controls=$("");var $toggleControl=$toggle.clone(true).addClass($t.parent().hasClass("InputfieldRepeaterOff")?"fa-toggle-off":"fa-toggle-on");var $deleteControl=$delete.clone(true);var $collapseControl=$t.find(".toggle-icon");var $insertBeforeControl=$insertBefore.clone(true);var $insertAfterControl=$insertAfter.clone(true);$controls.prepend($collapseControl);$controls.prepend($insertBeforeControl);$controls.prepend($insertAfterControl);if($t.closest(".InputfieldRepeater").hasClass("InputfieldRepeaterHasSettings")){var $settingsToggle=$("").attr("title",cfg.labels.settings);$controls.prepend($settingsToggle)}if(allowClone)$controls.prepend($clone.clone(true));$controls.prepend($toggleControl);$controls.prepend($deleteControl);$t.prepend($controls);$controls.css("background-color",$t.css("background-color"))}adjustItemLabel($item,false)})}function initRepeater($this){var $inputfields,$inputfieldRepeater,isItem;if($this.hasClass("InputfieldRepeaterItem")){$inputfields=$this;$inputfieldRepeater=$this.closest(".InputfieldRepeater");isItem=true}else{$inputfields=$this.find(".Inputfields:eq(0)");$inputfieldRepeater=$this;isItem=false}if($inputfields.hasClass("InputfieldRepeaterInit"))return;var renderValueMode=$inputfields.closest(".InputfieldRenderValueMode").length>0;$inputfields.addClass("InputfieldRepeaterInit");if(isItem){initHeaders($this.children(".InputfieldHeader"),$inputfieldRepeater,renderValueMode)}else{initHeaders($(".InputfieldRepeaterItem > .InputfieldHeader",$this),$inputfieldRepeater,renderValueMode)}if(renderValueMode){initDepths($inputfieldRepeater);return}$(".InputfieldRepeaterTrash",$this).hover(function(){var $label=$(this).closest("label");if(!$label.parents().hasClass("InputfieldRepeaterDeletePending"))$label.addClass("ui-state-error");$label.find(".InputfieldRepeaterItemControls").css("background-color",$label.css("background-color"))},function(){var $label=$(this).closest("label");if(!$label.parent().hasClass("InputfieldRepeaterDeletePending"))$label.removeClass("ui-state-error");$label.find(".InputfieldRepeaterItemControls").css("background-color",$label.css("background-color"))});if(isItem)$inputfields=$inputfieldRepeater.find(".Inputfields:eq(0)");initSortable($inputfieldRepeater,$inputfields);$(".InputfieldRepeaterAddLink:not(.InputfieldRepeaterAddLinkInit)",$inputfieldRepeater).addClass("InputfieldRepeaterAddLinkInit").click(eventAddLinkClick);if($inputfieldRepeater.hasClass("InputfieldRepeaterMax")){checkMinMax($inputfieldRepeater)}}function checkMinMax($inputfieldRepeater){if(!$inputfieldRepeater.hasClass("InputfieldRepeaterMax")&&!$inputfieldRepeater.hasClass("InputfieldRepeaterMin"))return;var max=parseInt($inputfieldRepeater.attr("data-max"));var min=parseInt($inputfieldRepeater.attr("data-min"));if(max<=0&&min<=0)return;var $content=$inputfieldRepeater.children(".InputfieldContent");var num=$content.children(".Inputfields").children("li:not(.InputfieldRepeaterDeletePending):not(.InputfieldRepeaterOff):visible").length;var $addItem=$content.children(".InputfieldRepeaterAddItem");var cloneChange="";var trashChange="";if(max>0){if(num>=max){$addItem.hide();cloneChange="hide"}else if(!$addItem.is(":visible")){$addItem.show();cloneChange="show"}}if(min>0){if(num<=min){trashChange="hide";$content.addClass("InputfieldRepeaterTrashHidden")}else if($content.hasClass("InputfieldRepeaterTrashHidden")){$content.removeClass("InputfieldRepeaterTrashHidden");trashChange="show"}}if(cloneChange.length||trashChange.length){var $items=$content.children(".Inputfields").children(".InputfieldRepeaterItem");if(cloneChange.length){$items.each(function(){var $clone=$(this).children(".InputfieldHeader").find(".InputfieldRepeaterClone");if(cloneChange==="show"){$clone.removeClass("pw-icon-disabled")}else{$clone.addClass("pw-icon-disabled")}})}if(trashChange.length){$items.each(function(){var $header=$(this).children(".InputfieldHeader");var $trash=$header.find(".InputfieldRepeaterTrash");var $toggle=$header.find(".InputfieldRepeaterToggle.fa-toggle-on");if(trashChange==="show"){$trash.removeClass("pw-icon-disabled");$toggle.removeClass("pw-icon-disabled")}else{$trash.addClass("pw-icon-disabled");$toggle.addClass("pw-icon-disabled")}});if(trashChange=="hide"){$content.children(".Inputfields").children("li.InputfieldRepeaterDeletePending").each(function(){var $trash=$(this).children(".InputfieldHeader").find(".InputfieldRepeaterTrash");$trash.removeClass("pw-icon-disabled")})}}}}function scrollToItem($item){$("html, body").animate({scrollTop:$item.offset().top-10},250,"swing")}function runScripts(data){if(data.indexOf("<\/script>")==-1)return;var d=document.createElement("div");d.innerHTML=data;var scripts=d.querySelectorAll(".Inputfield script");$(scripts).each(function(){$.globalEval(this.text||this.textContent||this.innerHTML||"")})}function updateState($item){if($item.closest(".InputfieldRepeaterRememberOpen").length<1)return;var val="";$(".InputfieldRepeaterItem:not(.InputfieldStateCollapsed)").each(function(){var id=parseInt($(this).attr("data-page"));if(id>0){val+=id+"|"}});$.cookie("repeaters_open",val)}function init(){$(".InputfieldRepeater").each(function(){initRepeater($(this))});$(document).on("reloaded",".InputfieldRepeater",eventReloaded).on("click",".InputfieldRepeaterTrash",eventDeleteClick).on("dblclick",".InputfieldRepeaterTrash",eventDeleteDblClick).on("click",".InputfieldRepeaterClone",eventCloneClick).on("click",".InputfieldRepeaterSettingsToggle",eventSettingsClick).on("dblclick",".InputfieldRepeaterToggle",eventOpenAllClick).on("click",".InputfieldRepeaterToggle",eventToggleClick).on("opened",".InputfieldRepeaterItem",eventItemOpened).on("closed",".InputfieldRepeaterItem",eventItemClosed).on("openReady",".InputfieldRepeaterItem",eventItemOpenReady).on("click",".InputfieldRepeaterInsertBefore",eventInsertBeforeClick).on("click",".InputfieldRepeaterInsertAfter",eventInsertAfterClick).on("mouseover",".InputfieldRepeaterInsertBefore",eventInsertMouseover).on("mouseover",".InputfieldRepeaterInsertAfter",eventInsertMouseover).on("mouseout",".InputfieldRepeaterInsertAfter",eventInsertMouseout)}init()}jQuery(document).ready(function($){InputfieldRepeater($)});
\ No newline at end of file
diff --git a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.module b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.module
index 15a5b903..19cc1381 100644
--- a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.module
+++ b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.module
@@ -26,9 +26,9 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
return array(
'title' => __('Repeater', __FILE__), // Module Title
'summary' => __('Repeats fields from another template. Provides the input for FieldtypeRepeater.', __FILE__), // Module Summary
- 'version' => 107,
+ 'version' => 108,
'requires' => 'FieldtypeRepeater',
- );
+ );
}
/**
@@ -112,8 +112,9 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
*/
public function init() {
parent::init();
- if(is_null($this->page)) $this->page = $this->wire('pages')->newNullPage();
- $this->attr('value', $this->wire('pages')->newPageArray());
+ $pages = $this->wire()->pages;
+ if(is_null($this->page)) $this->page = $pages->newNullPage();
+ $this->attr('value', $pages->newPageArray());
}
/**
@@ -128,11 +129,11 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
public function ___renderRepeaterLabel($label, $cnt, Page $page) {
// situations where we skip the render of repeater label because it is not needed
- $repeaterEditID = (int) $this->wire('input')->get('repeater_edit');
- if($repeaterEditID && $repeaterEditID == $page->id) {
+ $repeaterEditID = (int) $this->wire()->input->get('repeater_edit');
+ if($repeaterEditID && $repeaterEditID === $page->id) {
// edit of item requested in URL that matches given $page
return $label;
- } else if(count($_POST) && !$this->wire('config')->ajax) {
+ } else if(count($_POST) && !$this->wire()->config->ajax) {
// POST request that is not ajax
return $label;
}
@@ -154,7 +155,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
// formatted {label}
$out = $page->getMarkup($repeaterTitle);
- } else if(!$hasCnt && $this->wire('sanitizer')->fieldName($repeaterTitle) === $repeaterTitle) {
+ } else if(!$hasCnt && $this->wire()->sanitizer->fieldName($repeaterTitle) === $repeaterTitle) {
// just a single field name
$value = $page->getFormatted($repeaterTitle);
if(is_object($value)) {
@@ -321,6 +322,10 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
*
*/
protected function buildForm($itemID = 0, $loadInputsForIDs = null) {
+
+ $input = $this->wire()->input;
+ $session = $this->wire()->session;
+ $modules = $this->wire()->modules;
// if it's already been built, then return the cached version
if(!is_null($this->form)) return $this->form;
@@ -352,12 +357,12 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
$openIDs = array();
if((int) $this->field->get('rememberOpen')) {
$this->addClass('InputfieldRepeaterRememberOpen', 'wrapClass');
- $openIDs = $this->wire('input')->cookie('repeaters_open');
+ $openIDs = $input->cookie('repeaters_open');
if($openIDs) $openIDs = explode('|', trim($openIDs, '|'));
if(!is_array($openIDs)) $openIDs = array();
}
// merge with any open IDs in session
- $_openIDs = $this->wire('session')->getFor($this, 'openIDs');
+ $_openIDs = $session->getFor($this, 'openIDs');
if(is_array($_openIDs) && !empty($_openIDs)) {
$openIDs = array_merge($openIDs, array_values($_openIDs));
}
@@ -378,7 +383,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
$cnt = 0;
$numVisible = 0;
$numOpen = 0;
- $isPost = $this->wire('input')->requestMethod('POST');
+ $isPost = $input->requestMethod('POST');
$isSingle = $this->singleMode;
// create field for each repeater iteration
@@ -413,20 +418,24 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
$depth = null;
} else {
// also add a delete checkbox to the repeater page fields
- $delete = $this->wire('modules')->get('InputfieldCheckbox');
+ /** @var InputfieldCheckbox $delete */
+ $delete = $modules->get('InputfieldCheckbox');
$delete->attr('id+name', "delete_repeater{$page->id}");
$delete->addClass('InputfieldRepeaterDelete', 'wrapClass');
$delete->label = $this->_('Delete');
$delete->attr('value', $page->id);
- $sort = $this->wire('modules')->get('InputfieldHidden');
+ /** @var InputfieldHidden $sort */
+ $sort = $modules->get('InputfieldHidden');
$sort->attr('id+name', "sort_repeater{$page->id}");
$sort->class = 'InputfieldRepeaterSort';
+ $sort->addClass('InputfieldRepeaterItemSort', 'wrapClass');
$sort->label = $this->_('Sort');
$sort->attr('value', $cnt);
if($this->repeaterDepth > 0) {
- $depth = $this->wire('modules')->get('InputfieldHidden');
+ /** @var InputfieldHidden $depth */
+ $depth = $modules->get('InputfieldHidden');
$depth->attr('id+name', "depth_repeater{$page->id}");
$depth->addClass('InputfieldRepeaterItemDepth', 'wrapClass');
$depth->label = $this->_('Depth');
@@ -437,14 +446,16 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
$depth = null;
}
}
-
- $loaded = $this->wire('modules')->get('InputfieldHidden');
+
+ /** @var InputfieldHidden $loaded */
+ $loaded = $modules->get('InputfieldHidden');
$loaded->attr('id+name', "loaded_repeater{$page->id}");
$loaded->attr('value', $isLoaded ? 1 : 0);
$loaded->set('renderValueAsInput', true);
$loaded->class = 'InputfieldRepeaterLoaded';
- $wrap = $this->wire('modules')->get('InputfieldFieldset');
+ /** @var InputfieldFieldset $wrap */
+ $wrap = $modules->get('InputfieldFieldset');
$wrap->addClass('InputfieldRepeaterItem InputfieldNoFocus');
if(!$isPost) {
$wrap->entityEncodeLabel = false;
@@ -495,7 +506,8 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
if(!$isSingle) {
// add a hidden field that will be populated with a positive value for all visible repeater items
// this is so that processInput can see this item should be a published item
- $f = $this->wire('modules')->get('InputfieldHidden');
+ /** @var InputfieldHidden $f */
+ $f = $modules->get('InputfieldHidden');
$f->attr('name', "publish_repeater{$page->id}");
$f->attr('class', 'InputfieldRepeaterPublish');
@@ -547,7 +559,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
foreach($form->getAll() as $inputfield) {
$idAttr = $inputfield->attr('id');
$this->renderReadyInputfield($inputfield, $form, $this->renderValueMode);
- $jsValue = $this->wire('config')->js($idAttr);
+ $jsValue = $this->wire()->config->js($idAttr);
if(!empty($jsValue)) {
$inputfield->appendMarkup .= "';
}
@@ -555,9 +567,12 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
} else if(!$isSingle) {
// create a new/blank item to be used as a template for any new items added
/** @var InputfieldWrapper $wrap */
- $wrap = $this->wire('modules')->get('InputfieldFieldset');
- $wrap->label = $this->renderRepeaterLabel($label, ++$cnt, new NullPage());
+ $wrap = $modules->get('InputfieldFieldset');
+ $wrap->entityEncodeLabel = false;
+ $label = $this->entityEncode($this->renderRepeaterLabel($label, ++$cnt, new NullPage()));
+ $wrap->label = "$label";
$wrap->class = 'InputfieldRepeaterItem InputfieldRepeaterNewItem';
+ $wrap->attr('data-depth', 0);
$wrap->collapsed = Inputfield::collapsedNo;
$form->add($wrap);
}
@@ -618,7 +633,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
if($clonePage && $clonePage->id) {
/** @var FieldtypeRepeater $fieldtype */
$fieldtype = $this->field->type;
- $readyPage = $this->wire('pages')->clone($clonePage, null, true,
+ $readyPage = $this->wire()->pages->clone($clonePage, null, true,
array('set' => array(
'name' => $fieldtype->getUniqueRepeaterPageName() . 'c', // trailing "c" indicates clone
'sort' => count($value)+1,
@@ -628,7 +643,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
);
$readyPage->set('_repeater_clone', $clonePage->id);
} else if(!$cloneItemID) {
- $notIDs = $this->wire('sanitizer')->intArray(explode(',', trim($this->wire('input')->get('repeater_not'), ',')));
+ $notIDs = $this->wire()->sanitizer->intArray(explode(',', trim($this->wire()->input->get('repeater_not'), ',')));
$readyPage = $this->getNextReadyPage($notIDs);
$readyPage->removeStatus(Page::statusHidden);
}
@@ -652,8 +667,8 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
*/
protected function renderAddLabel() {
$addLabel = $this->field->get('repeaterAddLabel');
- if($this->wire('languages')) {
- $language = $this->wire('user')->language;
+ if($this->wire()->languages) {
+ $language = $this->wire()->user->language;
if(!$language->isDefault()) {
$addLabel = $this->field->get("repeaterAddLabel$language");
}
@@ -672,11 +687,17 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
*/
public function renderReady(Inputfield $parent = null, $renderValueMode = false) {
- /** @var User $user */
- $user = $this->wire('user');
+ $user = $this->wire()->user;
+ $modules = $this->wire()->modules;
+
+ /** @var JqueryCore $jQueryCore */
+ $jQueryCore = $modules->get('JqueryCore');
+ $jQueryCore->use('cookie');
+
+ /** @var JqueryUI $jQueryUI */
+ $jQueryUI = $modules->get('JqueryUI');
+ $jQueryUI->use('vex');
- $this->wire('modules')->get('JqueryCore')->use('cookie');
- $this->wire('modules')->get('JqueryUI')->use('vex');
$this->preloadInputfieldAssets();
$min = (int) $this->repeaterMinItems;
@@ -714,7 +735,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
if($queryString) {}
- $this->wire('config')->js('InputfieldRepeater', array(
+ $this->wire()->config->js('InputfieldRepeater', array(
'editorUrl' => $editorUrl,
'labels' => array(
'remove' => $this->_x('Click to delete this item, or double-click to delete all', 'repeater-item-action'),
@@ -724,6 +745,9 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
'settings' => $this->_x('Show settings?', 'repeater-item-action'),
'openAll' => $this->_x('Open all items?', 'repeater-item-action'),
'collapseAll' => $this->_x('Collapse all items?', 'repeater-item-action'),
+ 'insertBefore' => $this->_x('Insert new item before this one', 'repeater-item-action'),
+ 'insertAfter' => $this->_x('Insert new item after this one', 'repeater-item-action'),
+ 'insertHere' => $this->_x('Insert new item here', 'repeater-item-action'),
'disabledMinMax' => $this->_('This action is disabled per min and/or max item settings.')
)
));
@@ -761,11 +785,11 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
*/
public function ___render() {
- $input = $this->wire('input');
+ $input = $this->wire()->input;
$noAjaxAdd = $this->field->get('repeaterLoading') == FieldtypeRepeater::loadingOff ? '1' : '';
- $ajax = $this->wire('config')->ajax;
+ $ajax = $this->wire()->config->ajax;
- if($ajax && $input->get('field') == $this->attr('name')) {
+ if($ajax && $input->get('field') === $this->attr('name')) {
$repeaterAdd = $input->get('repeater_add');
$repeaterEdit = (int) $input->get('repeater_edit');
$repeaterClone = (int) $input->get('repeater_clone');
@@ -841,7 +865,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
$sortChanged = false;
$value->setTrackChanges(true);
$pageIDs = array();
- $_openIDs = $this->wire('session')->getFor($this, 'openIDs');
+ $_openIDs = $this->wire()->session->getFor($this, 'openIDs');
if(!is_array($_openIDs)) $_openIDs = array();
$openIDs = $_openIDs; // these two are compared with each other at the end
$this->numRequiredEmpty = 0;
@@ -962,7 +986,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
}
// if openIDs value changed, update the session variable
- if($_openIDs !== $openIDs) $this->wire('session')->setFor($this, 'openIDs', $openIDs);
+ if($_openIDs !== $openIDs) $this->wire()->session->setFor($this, 'openIDs', $openIDs);
return $this;
}
@@ -979,7 +1003,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
*/
protected function formToPage(InputfieldWrapper $wrapper, Page $page, $level = 0) {
- $languages = $this->wire('languages');
+ $languages = $this->wire()->languages;
foreach($wrapper as $inputfield) {
@@ -1064,9 +1088,13 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
*
*/
public function set($key, $value) {
- if($key == 'page') $this->page = $value;
- else if($key == 'field') $this->field = $value;
- else return parent::set($key, $value);
+ if($key === 'page') {
+ $this->page = $value;
+ } else if($key === 'field') {
+ $this->field = $value;
+ } else {
+ return parent::set($key, $value);
+ }
return $this;
}
diff --git a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.scss b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.scss
index 9c03455b..3645553d 100644
--- a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.scss
+++ b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.scss
@@ -42,9 +42,14 @@
.InputfieldRepeaterClone,
.InputfieldRepeaterToggle,
.InputfieldRepeaterTrash,
+ .InputfieldRepeaterInsertBefore,
+ .InputfieldRepeaterInsertAfter,
.toggle-icon {
cursor: pointer;
float: right;
+ &:hover {
+ opacity: 0.8;
+ }
}
.InputfieldRepeaterTrash {
padding-right: 3px;
@@ -55,6 +60,12 @@
.InputfieldRepeaterClone {
margin-right: 1em;
}
+ .InputfieldRepeaterInsertBefore {
+ margin-right: 0.75em;
+ }
+ .InputfieldRepeaterInsertAfter {
+ margin-right: 1em;
+ }
.InputfieldRepeaterSettingsToggle {
margin-right: 1em;
}
@@ -70,6 +81,10 @@
}
}
+
+ & > .InputfieldContent > .Inputfields > .InputfieldRepeaterInsertItem {
+ opacity: 0.5;
+ }
.InputfieldStateCollapsed .InputfieldRepeaterSettingsToggle {
display: none;
diff --git a/wire/modules/Fieldtype/FieldtypeRepeater/RepeaterPage.php b/wire/modules/Fieldtype/FieldtypeRepeater/RepeaterPage.php
index 48d32e50..47245313 100644
--- a/wire/modules/Fieldtype/FieldtypeRepeater/RepeaterPage.php
+++ b/wire/modules/Fieldtype/FieldtypeRepeater/RepeaterPage.php
@@ -3,7 +3,7 @@
/**
* RepeaterPage represents an individual repeater page item
*
- * ProcessWire 3.x, Copyright 2020 by Ryan Cramer
+ * ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* https://processwire.com
*
*/
@@ -114,7 +114,7 @@ class RepeaterPage extends Page {
$grandparentName = $grandparent->name;
$prefix = FieldtypeRepeater::fieldPageNamePrefix; // for-field-
$forField = null;
- $fields = $this->wire('fields'); /** @var Fields $fields */
+ $fields = $this->wire()->fields;
if(strpos($grandparentName, $prefix) === 0) {
// determine field from grandparent name in format: for-field-1234
diff --git a/wire/modules/Fieldtype/FieldtypeRepeater/RepeaterPageArray.php b/wire/modules/Fieldtype/FieldtypeRepeater/RepeaterPageArray.php
index 05d72d01..d6dbd7a6 100644
--- a/wire/modules/Fieldtype/FieldtypeRepeater/RepeaterPageArray.php
+++ b/wire/modules/Fieldtype/FieldtypeRepeater/RepeaterPageArray.php
@@ -5,7 +5,7 @@
*
* Special PageArray for use by repeaters that includes a getNewItem() method
*
- * ProcessWire 3.x, Copyright 2018 by Ryan Cramer
+ * ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* https://processwire.com
*
*/
@@ -28,15 +28,49 @@ class RepeaterPageArray extends PageArray {
*/
protected $field = null;
+ /**
+ * Construct
+ *
+ * @param Page $parent
+ * @param Field $field
+ *
+ */
public function __construct(Page $parent, Field $field) {
$this->setParent($parent);
$this->setField($field);
parent::__construct();
}
+ /**
+ * Set parent
+ *
+ * @param Page $parent
+ *
+ */
public function setParent(Page $parent) { $this->parent = $parent; }
+
+ /**
+ * Get parent
+ *
+ * @return Page
+ *
+ */
public function getParent() { return $this->parent; }
+
+ /**
+ * Set field
+ *
+ * @param Field $field
+ *
+ */
public function setField(Field $field) { $this->field = $field; }
+
+ /**
+ * Get field
+ *
+ * @return Field
+ *
+ */
public function getField() { return $this->field; }
/**
@@ -132,6 +166,12 @@ class RepeaterPageArray extends PageArray {
parent::trackRemove($item, $key);
}
+ /**
+ * Debug info
+ *
+ * @return array
+ *
+ */
public function __debugInfo() {
$info = array(
'field' => $this->field ? $this->field->debugInfoSmall() : '',