mirror of
https://github.com/processwire/processwire.git
synced 2025-08-09 08:17:12 +02:00
Updates to FieldtypeRepeater and InputfieldRepeater to support single mode, as used by FieldtypeFieldsetPage
This commit is contained in:
@@ -531,27 +531,30 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
||||
*
|
||||
* @param Page $page
|
||||
* @param Field $field
|
||||
* @param PageArray $value
|
||||
* @param PageArray|Page $value
|
||||
* @param array $notIDs Optional Page IDs that should be excluded from the next ready page
|
||||
* @return Page
|
||||
*
|
||||
*/
|
||||
public function getNextReadyPage(Page $page, Field $field, PageArray $value, array $notIDs = array()) {
|
||||
public function getNextReadyPage(Page $page, Field $field, $value = null, array $notIDs = array()) {
|
||||
$readyPage = null;
|
||||
foreach($value as $item) {
|
||||
if($item->hasStatus(Page::statusUnpublished)
|
||||
&& $item->hasStatus(Page::statusHidden)
|
||||
&& $item->id
|
||||
&& substr($item->name, -1) !== 'c' // cloned item
|
||||
&& !in_array($item->id, $notIDs)) {
|
||||
// existing/unused ready item that we will reuse
|
||||
$readyPage = $item;
|
||||
// touch the modified date for existing page to identify it as still current
|
||||
$query = $this->wire('database')->prepare('UPDATE pages SET modified=NOW(), modified_users_id=:user_id WHERE id=:id');
|
||||
$query->bindValue(':id', $readyPage->id, \PDO::PARAM_INT);
|
||||
$query->bindValue(':user_id', $this->wire('user')->id, \PDO::PARAM_INT);
|
||||
$query->execute();
|
||||
break;
|
||||
if($value) {
|
||||
if($value instanceof Page) $value = array($value);
|
||||
foreach($value as $item) {
|
||||
if($item->hasStatus(Page::statusUnpublished)
|
||||
&& $item->hasStatus(Page::statusHidden)
|
||||
&& $item->id
|
||||
&& substr($item->name, -1) !== 'c' // cloned item
|
||||
&& !in_array($item->id, $notIDs)) {
|
||||
// existing/unused ready item that we will reuse
|
||||
$readyPage = $item;
|
||||
// touch the modified date for existing page to identify it as still current
|
||||
$query = $this->wire('database')->prepare('UPDATE pages SET modified=NOW(), modified_users_id=:user_id WHERE id=:id');
|
||||
$query->bindValue(':id', $readyPage->id, \PDO::PARAM_INT);
|
||||
$query->bindValue(':user_id', $this->wire('user')->id, \PDO::PARAM_INT);
|
||||
$query->execute();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!$readyPage) {
|
||||
@@ -931,11 +934,11 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
||||
* @return Page
|
||||
*
|
||||
*/
|
||||
protected function getRepeaterPageParent(Page $page, Field $field) {
|
||||
protected function getRepeaterPageParent(Page $page, Field $field) {
|
||||
|
||||
$repeaterParent = $this->getRepeaterParent($field);
|
||||
$parent = $repeaterParent->child('name=' . self::repeaterPageNamePrefix . $page->id . ', include=all');
|
||||
if($parent->id) return $parent;
|
||||
$parent = $repeaterParent->child('name=' . self::repeaterPageNamePrefix . $page->id . ', include=all');
|
||||
if($parent->id) return $parent;
|
||||
|
||||
$parent = $this->wire('pages')->newPage(array('template' => $repeaterParent->template));
|
||||
$parent->parent = $repeaterParent;
|
||||
@@ -1040,10 +1043,7 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
||||
$template = $this->wire(new Template());
|
||||
$template->name = $templateName;
|
||||
$template->fieldgroup = $fieldgroup;
|
||||
$template->flags = Template::flagSystem;
|
||||
$template->noChildren = 1;
|
||||
$template->noParents = 1; // prevents users from creating pages with this template, but not us
|
||||
$template->noGlobal = 1;
|
||||
$this->populateRepeaterTemplateSettings($template);
|
||||
$template->save();
|
||||
|
||||
if(!$template->id) throw new WireException("Unable to create repeater template: $templateName");
|
||||
@@ -1057,6 +1057,19 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate the settings for a newly created repeater template
|
||||
*
|
||||
* @param Template $template
|
||||
*
|
||||
*/
|
||||
protected function populateRepeaterTemplateSettings(Template $template) {
|
||||
$template->flags = Template::flagSystem;
|
||||
$template->noChildren = 1;
|
||||
$template->noParents = 1; // prevents users from creating pages with this template, but not us
|
||||
$template->noGlobal = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the sanitization and convertion to PageArray value
|
||||
*
|
||||
@@ -1146,8 +1159,6 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
||||
/**
|
||||
* Perform output formatting on the value delivered to the API
|
||||
*
|
||||
* If the repeaterMaxItems setting is 1, then we format the value to dereference as single Page rather than a PageArray.
|
||||
*
|
||||
* This method is only used when $page->outputFormatting is true.
|
||||
*
|
||||
* @param Page $page
|
||||
@@ -1162,13 +1173,6 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
||||
|
||||
if(!$value instanceof PageArray) $value = $this->getBlankValue($page, $field);
|
||||
|
||||
/* TBA
|
||||
if($field->repeaterMaxItems == 1) {
|
||||
if(count($value)) $value = $value->first();
|
||||
else $value = new NullPage();
|
||||
}
|
||||
*/
|
||||
|
||||
// used as a clone if a formatted version of $value is different from non-formatted
|
||||
$formatted = null;
|
||||
$cnt = 0;
|
||||
@@ -1330,7 +1334,9 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
||||
|
||||
if($value instanceof RepeaterPage) {
|
||||
// for FieldsetPage compatibility
|
||||
$pageArray = $this->getBlankValue($page, $field);
|
||||
$pageArrayClass = $this->getPageArrayClass();
|
||||
/** @var RepeaterPageArray $pageArray */
|
||||
$pageArray = $this->wire(new $pageArrayClass($page, $field));
|
||||
$pageArray->add($value);
|
||||
$pageArray->resetTrackChanges();
|
||||
$value = $pageArray;
|
||||
@@ -1565,7 +1571,7 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
||||
*
|
||||
*/
|
||||
public function ___cloneField(Field $field) {
|
||||
throw new WireException("Sorry, repeater fields are not currently cloneable.");
|
||||
throw new WireException($this->className() . " does not currently support field cloning.");
|
||||
/*
|
||||
$field = parent::___cloneField($field);
|
||||
$field->parent_id = null;
|
||||
@@ -1644,38 +1650,44 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
||||
*
|
||||
*/
|
||||
public function ___install() {
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = $this->wire('pages');
|
||||
|
||||
$adminRoot = $this->wire('pages')->get($this->wire('config')->adminRootPageID);
|
||||
|
||||
$page = $this->wire('pages')->newPage(array('template' => 'admin'));
|
||||
$page->parent = $adminRoot;
|
||||
$page->status = Page::statusHidden | Page::statusLocked | Page::statusSystemID;
|
||||
$page->name = 'repeaters';
|
||||
$page->title = 'Repeaters';
|
||||
$page->sort = $adminRoot->numChildren;
|
||||
$page->save();
|
||||
$adminRoot = $pages->get($this->wire('config')->adminRootPageID);
|
||||
$page = $adminRoot->child("name=repeaters, template=admin, include=all");
|
||||
|
||||
if(!$page->id) {
|
||||
$page = $pages->newPage(array('template' => 'admin'));
|
||||
$page->parent = $adminRoot;
|
||||
$page->status = Page::statusHidden | Page::statusLocked | Page::statusSystemID;
|
||||
$page->name = 'repeaters';
|
||||
$page->title = 'Repeaters';
|
||||
$page->sort = $adminRoot->numChildren;
|
||||
$page->save();
|
||||
$this->message("Added page {$page->path}", Notice::debug);
|
||||
}
|
||||
|
||||
$configData = array('repeatersRootPageID' => $page->id);
|
||||
$this->wire('modules')->saveModuleConfigData($this, $configData);
|
||||
|
||||
$this->message("Added page {$page->path}", Notice::debug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall the module
|
||||
* Uninstall the module (delete the repeaters page)
|
||||
*
|
||||
*/
|
||||
public function ___uninstall() {
|
||||
|
||||
// delete the repeaters page
|
||||
// don't delete repeaters page unless actually for FieldtypeRepeater
|
||||
if($this->className() != 'FieldtypeRepeater') return;
|
||||
$page = $this->wire('pages')->get($this->repeatersRootPageID);
|
||||
if($page->id) {
|
||||
if($page->id && $page->name == 'repeaters' && $page->template == 'admin') {
|
||||
$page->addStatus(Page::statusSystemOverride);
|
||||
$page->removeStatus(Page::statusSystem);
|
||||
$page->removeStatus(Page::statusSystemID);
|
||||
$page->removeStatus(Page::statusSystemOverride);
|
||||
$page->removeStatus(Page::statusLocked);
|
||||
if($page->id) $this->wire('pages')->delete($page);
|
||||
$this->wire('pages')->delete($page);
|
||||
$this->message("Removed page {$page->path}", Notice::debug);
|
||||
}
|
||||
}
|
||||
|
@@ -283,11 +283,12 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
}
|
||||
|
||||
$minItems = $this->repeaterMinItems;
|
||||
$maxItems = $this->repeaterMaxItems;
|
||||
|
||||
// if there are a minimum required number of items, set them up now
|
||||
if(!$itemID && $minItems > 0) {
|
||||
$notIDs = $value->explode('id');
|
||||
while($value->count() < $this->repeaterMinItems) {
|
||||
while($value->count() < $minItems) {
|
||||
$item = $this->getNextReadyPage($notIDs);
|
||||
$value->add($item);
|
||||
$notIDs[] = $item->id;
|
||||
@@ -299,6 +300,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
$numVisible = 0;
|
||||
$numOpen = 0;
|
||||
$isPost = $this->wire('input')->requestMethod('POST');
|
||||
$isSingle = $minItems == 1 && $maxItems == 1;
|
||||
|
||||
// create field for each repeater iteration
|
||||
foreach($value as $key => $page) {
|
||||
@@ -310,11 +312,11 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
$isOn = $page->hasStatus(Page::statusOn);
|
||||
$isReadyItem = $isHidden && $isUnpublished;
|
||||
$isClone = $page->get('_repeater_clone');
|
||||
$isOpen = in_array($page->id, $openIDs) || $isClone;
|
||||
$isOpen = in_array($page->id, $openIDs) || $isClone || $isSingle;
|
||||
$isMinItem = $isReadyItem && $minItems && $cnt < $minItems;
|
||||
|
||||
if($isOpen && $numOpen > 0 && $this->accordionMode) $isOpen = false;
|
||||
|
||||
|
||||
// get the inputfields for the repeater page
|
||||
if(is_null($loadInputsForIDs) || in_array($page->id, $loadInputsForIDs) || $isOpen) {
|
||||
$inputfields = $this->getRepeaterItemInputfields($page);
|
||||
@@ -325,37 +327,44 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
}
|
||||
$inputfields->set('useDependencies', false);
|
||||
$this->wrappers[$page->id] = $inputfields;
|
||||
|
||||
// also add a delete checkbox to the repeater page fields
|
||||
$delete = $this->wire('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');
|
||||
$sort->attr('id+name', "sort_repeater{$page->id}");
|
||||
$sort->class = 'InputfieldRepeaterSort';
|
||||
$sort->label = $this->_('Sort');
|
||||
$sort->attr('value', $cnt);
|
||||
|
||||
if($this->repeaterDepth > 0) {
|
||||
$depth = $this->wire('modules')->get('InputfieldHidden');
|
||||
$depth->attr('id+name', "depth_repeater{$page->id}");
|
||||
$depth->class = 'InputfieldRepeaterDepth';
|
||||
$depth->label = $this->_('Depth');
|
||||
$depthValue = $page->getDepth();
|
||||
$depth->attr('value', $depthValue);
|
||||
$depth->set('renderValueAsInput', true);
|
||||
} else {
|
||||
|
||||
if($isSingle) {
|
||||
$delete = null;
|
||||
$sort = null;
|
||||
$depth = null;
|
||||
}
|
||||
$loaded = null;
|
||||
} else {
|
||||
// also add a delete checkbox to the repeater page fields
|
||||
$delete = $this->wire('modules')->get('InputfieldCheckbox');
|
||||
$delete->attr('id+name', "delete_repeater{$page->id}");
|
||||
$delete->addClass('InputfieldRepeaterDelete', 'wrapClass');
|
||||
$delete->label = $this->_('Delete');
|
||||
$delete->attr('value', $page->id);
|
||||
|
||||
$loaded = $this->wire('modules')->get('InputfieldHidden');
|
||||
$loaded->attr('id+name', "loaded_repeater{$page->id}");
|
||||
$loaded->attr('value', $isLoaded ? 1 : 0);
|
||||
$loaded->set('renderValueAsInput', true);
|
||||
$loaded->class = 'InputfieldRepeaterLoaded';
|
||||
$sort = $this->wire('modules')->get('InputfieldHidden');
|
||||
$sort->attr('id+name', "sort_repeater{$page->id}");
|
||||
$sort->class = 'InputfieldRepeaterSort';
|
||||
$sort->label = $this->_('Sort');
|
||||
$sort->attr('value', $cnt);
|
||||
|
||||
if($this->repeaterDepth > 0) {
|
||||
$depth = $this->wire('modules')->get('InputfieldHidden');
|
||||
$depth->attr('id+name', "depth_repeater{$page->id}");
|
||||
$depth->class = 'InputfieldRepeaterDepth';
|
||||
$depth->label = $this->_('Depth');
|
||||
$depthValue = $page->getDepth();
|
||||
$depth->attr('value', $depthValue);
|
||||
$depth->set('renderValueAsInput', true);
|
||||
} else {
|
||||
$depth = null;
|
||||
}
|
||||
|
||||
$loaded = $this->wire('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');
|
||||
$wrap->addClass('InputfieldRepeaterItem InputfieldNoFocus');
|
||||
@@ -379,7 +388,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
if($isClone) $wrap->addClass('InputfieldRepeaterItemClone');
|
||||
if($itemID) $wrap->addClass('InputfieldRepeaterItemRequested');
|
||||
|
||||
if($page->get('_repeater_delete')) {
|
||||
if($delete && $page->get('_repeater_delete')) {
|
||||
// something indicates it should already show delete state in editor
|
||||
$delete->attr('checked', 'checked');
|
||||
$wrap->addClass('InputfieldRepeaterDeletePending');
|
||||
@@ -400,36 +409,39 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
$hasErrors = count($inputfields->getErrors()) > 0;
|
||||
if($hasErrors) $wrap->icon = 'warning';
|
||||
|
||||
// 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');
|
||||
$f->attr('name', "publish_repeater{$page->id}");
|
||||
$f->attr('class', 'InputfieldRepeaterPublish');
|
||||
|
||||
if($isReadyItem) {
|
||||
// ready item
|
||||
$f->attr('value', 0);
|
||||
} else if($isUnpublished && !$isOn) {
|
||||
// unpublished item
|
||||
$f->attr('value', -1);
|
||||
} else {
|
||||
// published item
|
||||
$f->attr('value', 1);
|
||||
}
|
||||
|
||||
$wrap->add($f);
|
||||
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');
|
||||
$f->attr('name', "publish_repeater{$page->id}");
|
||||
$f->attr('class', 'InputfieldRepeaterPublish');
|
||||
|
||||
if($isUnpublished) {
|
||||
$wrap->addClass('InputfieldRepeaterUnpublished');
|
||||
if(!$isOn) $wrap->addClass('InputfieldRepeaterOff');
|
||||
if($isReadyItem) {
|
||||
// ready item
|
||||
$f->attr('value', 0);
|
||||
} else if($isUnpublished && !$isOn) {
|
||||
// unpublished item
|
||||
$f->attr('value', -1);
|
||||
} else {
|
||||
// published item
|
||||
$f->attr('value', 1);
|
||||
}
|
||||
|
||||
$wrap->add($f);
|
||||
|
||||
if($isUnpublished) {
|
||||
$wrap->addClass('InputfieldRepeaterUnpublished');
|
||||
if(!$isOn) $wrap->addClass('InputfieldRepeaterOff');
|
||||
}
|
||||
|
||||
$wrap->prepend($delete);
|
||||
$wrap->prepend($sort);
|
||||
if($depth) $wrap->prepend($depth);
|
||||
$wrap->prepend($loaded);
|
||||
} else {
|
||||
$wrap->add($inputfields);
|
||||
}
|
||||
|
||||
$wrap->add($inputfields);
|
||||
$wrap->prepend($delete);
|
||||
$wrap->prepend($sort);
|
||||
if($depth) $wrap->prepend($depth);
|
||||
$wrap->prepend($loaded);
|
||||
|
||||
|
||||
if($isMinItem) {
|
||||
// allow this ready item to be added so that minimum is met
|
||||
$wrap->addClass('InputfieldRepeaterMinItem');
|
||||
@@ -455,7 +467,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
$inputfield->appendMarkup .= "<script>ProcessWire.config['$idAttr'] = " . json_encode($jsValue) . ';</script>';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} 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');
|
||||
@@ -715,6 +727,8 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
*/
|
||||
public function ___processInput(WireInputData $input) {
|
||||
|
||||
$isSingle = $this->repeaterMinItems == 1 && $this->repeaterMaxItems == 1;
|
||||
|
||||
/** @var PageArray $value */
|
||||
$value = $this->attr('value');
|
||||
$loadedIDs = array();
|
||||
@@ -722,7 +736,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
// determine which repeater pages have data posted in this request
|
||||
foreach($value as $key => $page) {
|
||||
$loadedName = "loaded_repeater$page->id";
|
||||
if(((int) $input->$loadedName) > 0) $loadedIDs[$page->id] = $page->id;
|
||||
if($isSingle || ((int) $input->$loadedName) > 0) $loadedIDs[$page->id] = $page->id;
|
||||
}
|
||||
|
||||
$this->buildForm(0, $loadedIDs);
|
||||
@@ -741,33 +755,37 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
$isHidden = $page->isHidden();
|
||||
$isUnpublished = $page->isUnpublished();
|
||||
$isOn = $page->hasStatus(Page::statusOn);
|
||||
|
||||
$deleteName = "delete_repeater{$page->id}";
|
||||
$sortName = "sort_repeater{$page->id}";
|
||||
$publishName = "publish_repeater{$page->id}";
|
||||
$depthName = "depth_repeater{$page->id}";
|
||||
|
||||
if($input->$deleteName == $page->id) {
|
||||
$value->remove($page);
|
||||
$numChanges++;
|
||||
continue;
|
||||
}
|
||||
if($isSingle) {
|
||||
$publishName = '';
|
||||
} else {
|
||||
$deleteName = "delete_repeater{$page->id}";
|
||||
$sortName = "sort_repeater{$page->id}";
|
||||
$publishName = "publish_repeater{$page->id}";
|
||||
$depthName = "depth_repeater{$page->id}";
|
||||
|
||||
$sort = $input->$sortName;
|
||||
// skip pages that don't appear in the POST data (most likely ready pages)
|
||||
if(is_null($sort)) continue;
|
||||
|
||||
$page->sort = (int) $sort;
|
||||
if($page->isChanged('sort')) {
|
||||
// $this->message("Sort changed for field {$this->field} page {$page->id}", Notice::debug);
|
||||
$sortChanged = true;
|
||||
}
|
||||
|
||||
if($this->repeaterDepth > 0) {
|
||||
$depth = (int) $input->$depthName;
|
||||
if($page->getDepth() != $depth) {
|
||||
$page->setDepth($depth);
|
||||
if($input->$deleteName == $page->id) {
|
||||
$value->remove($page);
|
||||
$numChanges++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$sort = $input->$sortName;
|
||||
// skip pages that don't appear in the POST data (most likely ready pages)
|
||||
if(is_null($sort)) continue;
|
||||
|
||||
$page->sort = (int) $sort;
|
||||
if($page->isChanged('sort')) {
|
||||
// $this->message("Sort changed for field {$this->field} page {$page->id}", Notice::debug);
|
||||
$sortChanged = true;
|
||||
}
|
||||
|
||||
if($this->repeaterDepth > 0) {
|
||||
$depth = (int) $input->$depthName;
|
||||
if($page->getDepth() != $depth) {
|
||||
$page->setDepth($depth);
|
||||
$numChanges++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -780,7 +798,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
$page->setQuietly('_repeater_errors', $numErrors); // signal to FieldtypeRepeater::savePageField() that page has errors
|
||||
$page->setQuietly('_repeater_processed', true); // signal to FieldtypeRepeater::savePageField() that page had input processed
|
||||
$this->formToPage($wrapper, $page);
|
||||
$publish = (int) $input->$publishName;
|
||||
$publish = $isSingle ? 0 : (int) $input->$publishName;
|
||||
|
||||
if($publish > 0 && ($isHidden || $isUnpublished)) {
|
||||
// publish requested (publish=1)
|
||||
@@ -808,7 +826,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
$numChanges++;
|
||||
}
|
||||
|
||||
if($this->field->get('repeaterLoading') == FieldtypeRepeater::loadingOff) {
|
||||
if(!$isSingle && $this->field->get('repeaterLoading') == FieldtypeRepeater::loadingOff) {
|
||||
$numNewItems = (int) $input["_{$this->name}_add_items"];
|
||||
if($numNewItems) {
|
||||
// iterate through each new item added for non-ajax mode
|
||||
@@ -907,6 +925,24 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set attribute
|
||||
*
|
||||
* @param array|string $key
|
||||
* @param array|int|string $value
|
||||
* @return InputfieldRepeater|Inputfield
|
||||
*
|
||||
*/
|
||||
public function setAttribute($key, $value) {
|
||||
if($key === 'value' && $value instanceof Page) {
|
||||
if($this->field && method_exists($this->field->type, 'getRepeaterPageArray')) {
|
||||
if(!$value->id) $value = null;
|
||||
$value = $this->field->type->getRepeaterPageArray($this->page, $this->field, $value);
|
||||
}
|
||||
}
|
||||
return parent::setAttribute($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the repeater wrappers (InputfieldWrappers) indexed by repeater page ID
|
||||
*
|
||||
|
@@ -114,7 +114,14 @@ class RepeaterPage extends Page {
|
||||
|
||||
return $this->forField;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get property
|
||||
*
|
||||
* @param string $key
|
||||
* @return int|mixed|null
|
||||
*
|
||||
*/
|
||||
public function get($key) {
|
||||
$value = parent::get($key);
|
||||
if($key === 'depth' && is_null($value)) {
|
||||
@@ -122,7 +129,13 @@ class RepeaterPage extends Page {
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get depth
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
*/
|
||||
public function getDepth() {
|
||||
if(is_null($this->depth)) {
|
||||
$this->depth = 0;
|
||||
@@ -131,7 +144,13 @@ class RepeaterPage extends Page {
|
||||
}
|
||||
return $this->depth;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set depth
|
||||
*
|
||||
* @param int $depth
|
||||
*
|
||||
*/
|
||||
public function setDepth($depth) {
|
||||
$name = $this->name;
|
||||
$_name = $name;
|
||||
|
Reference in New Issue
Block a user