1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-12 17:54:44 +02:00

Update repeaters clone feature to clone in place, next to item cloned from (rather than inserting newly cloned item at bottom)

This commit is contained in:
Ryan Cramer
2021-10-21 13:12:30 -04:00
parent a4555e1271
commit b269c1cad7
3 changed files with 74 additions and 19 deletions

View File

@@ -161,8 +161,31 @@ function InputfieldRepeater($) {
var itemID = $item.attr('data-page'); var itemID = $item.attr('data-page');
var $addLink = $item.closest('.InputfieldRepeater').children('.InputfieldContent') var $addLink = $item.closest('.InputfieldRepeater').children('.InputfieldContent')
.children('.InputfieldRepeaterAddItem').find('.InputfieldRepeaterAddLink:eq(0)'); .children('.InputfieldRepeaterAddItem').find('.InputfieldRepeaterAddLink:eq(0)');
// $('html, body').animate({ scrollTop: $addLink.offset().top - 100}, 250, 'swing');
$item.siblings('.InputfieldRepeaterInsertItem').remove();
var depth = getItemDepth($item);
var $newItem = $item.siblings('.InputfieldRepeaterNewItem').clone();
var $nextItem = $item.next('.InputfieldRepeaterItem');
var nextItemDepth = $nextItem.length ? getItemDepth($nextItem) : depth;
var $prevItem = $item.prev('.InputfieldRepeaterItem');
var prevItemDepth = $prevItem.length ? getItemDepth($prevItem) : depth;
var insertBefore = depth < nextItemDepth;
if(depth < nextItemDepth) insertBefore = true;
$newItem.addClass('InputfieldRepeaterInsertItem').attr('id', $newItem.attr('id') + '-clone');
$newItem.find('.InputfieldHeader').html("<i class='fa fa-spin fa-spinner'></i>");
if(insertBefore) {
depth = getInsertBeforeItemDepth($item);
$newItem.addClass('InputfieldRepeaterInsertItemBefore');
$newItem.insertBefore($item);
} else {
depth = getInsertAfterItemDepth($item);
$newItem.addClass('InputfieldRepeaterInsertItemAfter');
$newItem.insertAfter($item);
}
setItemDepth($newItem, depth);
$newItem.show();
$addLink.attr('data-clone', itemID).click(); $addLink.attr('data-clone', itemID).click();
$('html, body').animate({ scrollTop: $addLink.offset().top - 100}, 250, 'swing');
}); });
return false; return false;
}; };
@@ -515,26 +538,34 @@ function InputfieldRepeater($) {
if(currentlyAddingItem) return false; if(currentlyAddingItem) return false;
currentlyAddingItem = true; currentlyAddingItem = true;
if(insertTimeout) clearTimeout(insertTimeout); if(insertTimeout) clearTimeout(insertTimeout);
var depth = getInsertItemDepth($item, insertBefore); var depth = getInsertItemDepth($item, insertBefore);
var $insertItem = $item.siblings('.InputfieldRepeaterInsertItem'); var $oldInsertItem = $item.siblings('.InputfieldRepeaterInsertItem');
if($insertItem.length) { if($oldInsertItem.length) $oldInsertItem.remove();
$insertItem.remove(); var $insertItem = $item.siblings('.InputfieldRepeaterNewItem').clone()
}
var $placeholder = $item.siblings('.InputfieldRepeaterNewItem').clone()
.removeClass('.InputfieldRepeaterNewItem').addClass('InputfieldRepeaterInsertItem'); .removeClass('.InputfieldRepeaterNewItem').addClass('InputfieldRepeaterInsertItem');
$placeholder.attr('id', $placeholder.attr('id') + '-placeholder'); $insertItem.attr('id', $insertItem.attr('id') + '-placeholder');
$placeholder.find('.InputfieldHeader').html("<i class='fa fa-spin fa-spinner'></i>"); $insertItem.find('.InputfieldHeader').html("<i class='fa fa-spin fa-spinner'></i>");
if(insertBefore) { if(insertBefore) {
$placeholder.insertBefore($item); $insertItem.insertBefore($item);
} else { } else {
$placeholder.insertAfter($item); $insertItem.insertAfter($item);
}
if(depth > 0) setItemDepth($insertItem, depth);
$insertItem.show();
if(!insertBefore && !$item.hasClass('InputfieldStateCollapsed')) scrollToItem($insertItem);
$insertItem.children('.InputfieldHeader').effect('highlight', {}, 500);
// var $addLinks = $item.parent('.Inputfields').siblings('.InputfieldRepeaterAddItem').find('.InputfieldRepeaterAddLink:eq(0)').click();
var $addLinks = $item.parent('.Inputfields').siblings('.InputfieldRepeaterAddItem').find('.InputfieldRepeaterAddLink');
if($addLinks.length === 1) {
// add new item now
$addLinks.eq(0).click();
} else if($addLinks.length > 1) {
// we need to know what type of link to add (i.e. matrix)
$item.trigger('repeaterinsert', [ $insertItem, $item, insertBefore ]);
currentlyAddingItem = false;
} }
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();
} }
/** /**
@@ -576,6 +607,7 @@ function InputfieldRepeater($) {
if(insertBefore) { if(insertBefore) {
depth = getInsertBeforeItemDepth($item); depth = getInsertBeforeItemDepth($item);
$newItem.addClass('InputfieldRepeaterInsertItemBefore');//.insertBefore($item); $newItem.addClass('InputfieldRepeaterInsertItemBefore');//.insertBefore($item);
$newItem.addClass('hov');
} else { } else {
depth = getInsertAfterItemDepth($item); depth = getInsertAfterItemDepth($item);
$newItem.addClass('InputfieldRepeaterInsertItemAfter');//.insertAfter($item); $newItem.addClass('InputfieldRepeaterInsertItemAfter');//.insertAfter($item);
@@ -694,6 +726,10 @@ function InputfieldRepeater($) {
} }
} }
function getItemLabel($item) {
return $item.children('.InputfieldHeader').children('.InputfieldRepeaterItemLabel');
}
/*** SORT FUNCTIONS ***********************************************************************************/ /*** SORT FUNCTIONS ***********************************************************************************/
function setItemSort($item, sort) { function setItemSort($item, sort) {
@@ -713,6 +749,21 @@ function InputfieldRepeater($) {
.children('.InputfieldRepeaterItemSort').find('.InputfieldRepeaterSort'); .children('.InputfieldRepeaterItemSort').find('.InputfieldRepeaterSort');
} }
/**
* Is item allowed to be sorted to its current position?
*
* @param $item
*
*/
function sortableItemAllowed($item) {
if($item.hasClass('InputfieldRepeaterMatrixItem')) {
if(typeof InputfieldRepeaterMatrixTools !== "undefined") {
return InputfieldRepeaterMatrixTools.sortableItemAllowed($item);
}
}
return true;
}
/*** DEPTH FUNCTIONS **********************************************************************************/ /*** DEPTH FUNCTIONS **********************************************************************************/
/** /**
@@ -957,6 +1008,8 @@ function InputfieldRepeater($) {
sortableDepth(ui, maxDepth, true); sortableDepth(ui, maxDepth, true);
} }
if(!sortableItemAllowed(ui.item)) return false;
// update/move and show depth children // update/move and show depth children
if(maxDepth > 0 && familyFriendly && depthChildren.length) { if(maxDepth > 0 && familyFriendly && depthChildren.length) {
var $item = ui.item; var $item = ui.item;
@@ -1310,6 +1363,7 @@ function InputfieldRepeater($) {
.on('click', '.InputfieldRepeaterInsertAfter', eventInsertAfterClick) .on('click', '.InputfieldRepeaterInsertAfter', eventInsertAfterClick)
.on('mouseover', '.InputfieldRepeaterInsertBefore', eventInsertMouseover) .on('mouseover', '.InputfieldRepeaterInsertBefore', eventInsertMouseover)
.on('mouseover', '.InputfieldRepeaterInsertAfter', eventInsertMouseover) .on('mouseover', '.InputfieldRepeaterInsertAfter', eventInsertMouseover)
.on('mouseout', '.InputfieldRepeaterInsertBefore', eventInsertMouseout)
.on('mouseout', '.InputfieldRepeaterInsertAfter', eventInsertMouseout); .on('mouseout', '.InputfieldRepeaterInsertAfter', eventInsertMouseout);
} }

File diff suppressed because one or more lines are too long

View File

@@ -26,7 +26,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
return array( return array(
'title' => __('Repeater', __FILE__), // Module Title 'title' => __('Repeater', __FILE__), // Module Title
'summary' => __('Repeats fields from another template. Provides the input for FieldtypeRepeater.', __FILE__), // Module Summary 'summary' => __('Repeats fields from another template. Provides the input for FieldtypeRepeater.', __FILE__), // Module Summary
'version' => 108, 'version' => 109,
'requires' => 'FieldtypeRepeater', 'requires' => 'FieldtypeRepeater',
); );
} }
@@ -456,7 +456,8 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
/** @var InputfieldFieldset $wrap */ /** @var InputfieldFieldset $wrap */
$wrap = $modules->get('InputfieldFieldset'); $wrap = $modules->get('InputfieldFieldset');
$wrap->addClass('InputfieldRepeaterItem InputfieldNoFocus'); $wrapClasses = array_unique(array('InputfieldRepeaterItem', $this->className() . 'Item', 'InputfieldNoFocus'));
$wrap->addClass(implode(' ', $wrapClasses));
if(!$isPost) { if(!$isPost) {
$wrap->entityEncodeLabel = false; $wrap->entityEncodeLabel = false;
$wrap->label = $wrap->label =