diff --git a/wire/core/Fieldgroups.php b/wire/core/Fieldgroups.php
index 14e374ee..f1133640 100644
--- a/wire/core/Fieldgroups.php
+++ b/wire/core/Fieldgroups.php
@@ -7,12 +7,16 @@
* #pw-body For full details on all methods available in a Fieldgroup, be sure to also see the `WireArray` class.
* #pw-var $fieldgroups
*
- * ProcessWire 3.x, Copyright 2016 by Ryan Cramer
+ * ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @method int saveContext(Fieldgroup $fieldgroup)
* @method array getExportData(Fieldgroup $fieldgroup)
* @method array setImportData(Fieldgroup $fieldgroup, array $data)
+ *
+ * @method void fieldRemoved(Fieldgroup $fieldgroup, Field $field)
+ * @method void fieldAdded(Fieldgroup $fieldgroup, Field $field)
+ * @method void sorted(Fieldgroup $fieldgroup, array $oldOrder, array $newOrder)
*
*
*/
@@ -25,8 +29,12 @@ class Fieldgroups extends WireSaveableItemsLookup {
* @var FieldgroupsArray
*
*/
- protected $fieldgroupsArray;
-
+ protected $fieldgroupsArray;
+
+ /**
+ * Init
+ *
+ */
public function init() {
$this->fieldgroupsArray = $this->wire(new FieldgroupsArray());
$this->load($this->fieldgroupsArray);
@@ -142,54 +150,80 @@ class Fieldgroups extends WireSaveableItemsLookup {
*/
public function ___save(Saveable $item) {
- $database = $this->wire('database');
+ $database = $this->wire()->database;
+
+ /** @var Fieldgroup $fieldgroup */
+ $fieldgroup = $item;
+ $datas = array();
+ $fieldsAdded = array();
+ $fieldsRemoved = array();
- /** @var Fieldgroup $item */
+ if($fieldgroup->id && $fieldgroup->removedFields) {
- if($item->id && $item->removedFields) {
-
- foreach($this->wire('templates') as $template) {
- if($template->fieldgroup->id !== $item->id) continue;
- foreach($item->removedFields as $field) {
+ foreach($this->wire()->templates as $template) {
+ if($template->fieldgroup->id !== $fieldgroup->id) continue;
+ foreach($fieldgroup->removedFields as $field) {
// make sure the field is valid to delete from this template
- $error = $this->isFieldNotRemoveable($field, $item, $template);
+ $error = $this->isFieldNotRemoveable($field, $fieldgroup, $template);
if($error !== false) throw new WireException("$error Save of fieldgroup changes aborted.");
if($field->type) $field->type->deleteTemplateField($template, $field);
- $item->finishRemove($field);
+ $fieldgroup->finishRemove($field);
+ $fieldsRemoved[] = $field;
}
}
- $item->resetRemovedFields();
+ $fieldgroup->resetRemovedFields();
}
- $contextData = array();
- if($item->id) {
- // save context data
- $query = $database->prepare("SELECT fields_id, data FROM fieldgroups_fields WHERE fieldgroups_id=:item_id");
- $query->bindValue(":item_id", (int) $item->id, \PDO::PARAM_INT);
+ if($fieldgroup->id) {
+ // load context data to populate back after fieldgroup save
+ $sql = 'SELECT fields_id, data FROM fieldgroups_fields WHERE fieldgroups_id=:fieldgroups_id';
+ $query = $database->prepare($sql);
+ $query->bindValue(':fieldgroups_id', (int) $fieldgroup->id, \PDO::PARAM_INT);
$query->execute();
/** @noinspection PhpAssignmentInConditionInspection */
while($row = $query->fetch(\PDO::FETCH_ASSOC)) {
- $contextData[$row['fields_id']] = $row['data'];
+ $fields_id = (int) $row['fields_id'];
+ $datas[$fields_id] = $row['data'];
}
$query->closeCursor();
}
+
+ $result = parent::___save($fieldgroup);
+
+ // identify any fields added
+ foreach($fieldgroup as $field) {
+ if(!array_key_exists($field->id, $datas)) {
+ $fieldsAdded[] = $field;
+ }
+ }
- $result = parent::___save($item);
-
- if(count($contextData)) {
+ if(count($datas)) {
// restore context data
- foreach($contextData as $fields_id => $data) {
- $fieldgroups_id = (int) $item->id;
- $fields_id = (int) $fields_id;
- $query = $database->prepare("UPDATE fieldgroups_fields SET data=:data WHERE fieldgroups_id=:fieldgroups_id AND fields_id=:fields_id"); // QA
- $query->bindValue(":data", $data, \PDO::PARAM_STR);
+ $fieldgroups_id = (int) $fieldgroup->id;
+ foreach($datas as $fields_id => $data) {
+ $sql = "UPDATE fieldgroups_fields SET data=:data WHERE fieldgroups_id=:fieldgroups_id AND fields_id=:fields_id";
+ $query = $database->prepare($sql);
+ if($data === null) {
+ $query->bindValue(":data", null, \PDO::PARAM_NULL);
+ } else {
+ $query->bindValue(":data", $data, \PDO::PARAM_STR);
+ }
$query->bindValue(":fieldgroups_id", $fieldgroups_id, \PDO::PARAM_INT);
$query->bindValue(":fields_id", $fields_id, \PDO::PARAM_INT);
$query->execute();
}
}
+ // trigger any fields added
+ foreach($fieldsAdded as $field) {
+ $this->fieldAdded($fieldgroup, $field);
+ }
+ // trigger any fieldsl removed
+ foreach($fieldsRemoved as $field) {
+ $this->fieldRemoved($fieldgroup, $field);
+ }
+
return $result;
}
@@ -270,7 +304,7 @@ class Fieldgroups extends WireSaveableItemsLookup {
foreach($contexts as $fieldID => $context) {
$field = $fieldgroup->getFieldContext((int) $fieldID);
if(!$field) continue;
- if($this->wire('fields')->saveFieldgroupContext($field, $fieldgroup)) $numSaved++;
+ if($this->wire()->fields->saveFieldgroupContext($field, $fieldgroup)) $numSaved++;
}
return $numSaved;
}
@@ -486,5 +520,28 @@ class Fieldgroups extends WireSaveableItemsLookup {
return false;
}
+ /**
+ * Hook called when field has been added to fieldgroup
+ *
+ * #pw-hooker
+ *
+ * @param Fieldgroup $fieldgroup
+ * @param Field $field
+ * @since 3.0.193
+ *
+ */
+ public function ___fieldAdded(Fieldgroup $fieldgroup, Field $field) { }
+
+ /**
+ * Hook called when field has been removed from fieldgroup
+ *
+ * #pw-hooker
+ *
+ * @param Fieldgroup $fieldgroup
+ * @param Field $field
+ * @since 3.0.193
+ *
+ */
+ public function ___fieldRemoved(Fieldgroup $fieldgroup, Field $field) { }
}
diff --git a/wire/core/WireSaveableItems.php b/wire/core/WireSaveableItems.php
index 15d0cd4f..76d709f0 100644
--- a/wire/core/WireSaveableItems.php
+++ b/wire/core/WireSaveableItems.php
@@ -6,7 +6,7 @@
* Wire Data Access Object, provides reusable capability for loading, saving, creating, deleting,
* and finding items of descending class-defined types.
*
- * ProcessWire 3.x, Copyright 2016 by Ryan Cramer
+ * ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @method WireArray load(WireArray $items, $selectors = null)
@@ -20,6 +20,8 @@
* @method void added(Saveable $item) #pw-hooker
* @method void deleted(Saveable $item) #pw-hooker
* @method void cloned(Saveable $item, Saveable $copy) #pw-hooker
+ * @method void renameReady(Saveable $item, $oldName, $newName)
+ * @method void renamed(Saveable $item, $oldName, $newName)
*
*
*/
@@ -256,6 +258,17 @@ abstract class WireSaveableItems extends Wire implements \IteratorAggregate {
$this->saveReady($item);
$data = $item->getTableData();
$binds = array();
+ $namePrevious = false;
+
+ if($id && $item->isChanged('name')) {
+ $query = $database->prepare("SELECT name FROM `$table` WHERE id=:id");
+ $query->bindValue(':id', $id, \PDO::PARAM_INT);
+ $query->execute();
+ $oldName = $query->fetchColumn();
+ $query->closeCursor();
+ if($oldName != $item->name) $namePrevious = $oldName;
+ if($namePrevious) $this->renameReady($item, $namePrevious, $item->name);
+ }
foreach($data as $key => $value) {
if(!$this->saveItemKey($key)) continue;
@@ -292,6 +305,7 @@ abstract class WireSaveableItems extends Wire implements \IteratorAggregate {
}
if($result) {
+ if($namePrevious) $this->renamed($item, $namePrevious, $item->name);
$this->saved($item);
$this->resetTrackChanges();
} else {
@@ -475,6 +489,16 @@ abstract class WireSaveableItems extends Wire implements \IteratorAggregate {
*/
public function ___cloneReady(Saveable $item, Saveable $copy) { }
+ /**
+ * Hook that runs right before item is to be renamed.
+ *
+ * @param Saveable $item
+ * @param string $oldName
+ * @param string $newName
+ *
+ */
+ public function ___renameReady(Saveable $item, $oldName, $newName) { }
+
/**
* Hook that runs right after an item has been saved.
*
@@ -517,8 +541,6 @@ abstract class WireSaveableItems extends Wire implements \IteratorAggregate {
/**
* Hook that runs right after an item has been cloned.
*
- * Unlike after(delete), it has already been confirmed that the item was indeed deleted.
- *
* @param Saveable $item
* @param Saveable $copy
*
@@ -526,6 +548,18 @@ abstract class WireSaveableItems extends Wire implements \IteratorAggregate {
public function ___cloned(Saveable $item, Saveable $copy) {
$this->log("Cloned '$item->name' to '$copy->name'", $item);
}
+
+ /**
+ * Hook that runs right after an item has been renamed.
+ *
+ * @param Saveable $item
+ * @param string $oldName
+ * @param string $newName
+ *
+ */
+ public function ___renamed(Saveable $item, $oldName, $newName) {
+ $this->log("Renamed $oldName to $newName", $item);
+ }
/**
* Enables use of $apivar('name') or wire()->apivar('name')
diff --git a/wire/core/WireSaveableItemsLookup.php b/wire/core/WireSaveableItemsLookup.php
index 763775a5..7c75486f 100644
--- a/wire/core/WireSaveableItemsLookup.php
+++ b/wire/core/WireSaveableItemsLookup.php
@@ -5,7 +5,7 @@
*
* Provides same functionality as WireSaveableItems except that this class includes joining/modification of a related lookup table
*
- * ProcessWire 3.x, Copyright 2016 by Ryan Cramer
+ * ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
*/
@@ -40,12 +40,13 @@ abstract class WireSaveableItemsLookup extends WireSaveableItems {
*/
protected function getLoadQuery($selectors = null) {
$query = parent::getLoadQuery($selectors);
- $database = $this->wire('database');
+ $database = $this->wire()->database;
$table = $database->escapeTable($this->getTable());
$lookupTable = $database->escapeTable($this->getLookupTable());
$lookupField = $database->escapeCol($this->getLookupField());
$query->select("$lookupTable.$lookupField"); // QA
- $query->leftjoin("$lookupTable ON $lookupTable.{$table}_id=$table.id ")->orderby("sort"); // QA
+ $query->leftjoin("$lookupTable ON $lookupTable.{$table}_id=$table.id ")->orderby("sort");
+ // $query->leftjoin("$lookupTable ON $lookupTable.{$table}_id=$table.id ")->orderby("$table.id, $lookupTable.sort");
return $query;
}
@@ -60,9 +61,9 @@ abstract class WireSaveableItemsLookup extends WireSaveableItems {
*
*/
protected function ___load(WireArray $items, $selectors = null) {
-
+
+ $database = $this->wire()->database;
$query = $this->getLoadQuery($selectors);
- $database = $this->wire('database');
$sql = $query->getQuery();
$stmt = $database->prepare($sql);
$stmt->execute();
@@ -70,6 +71,7 @@ abstract class WireSaveableItemsLookup extends WireSaveableItems {
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ /** @var HasLookupItems $item */
$item = $this->makeBlankItem();
$lookupValue = $row[$lookupField];
unset($row[$lookupField]);
@@ -93,6 +95,7 @@ abstract class WireSaveableItemsLookup extends WireSaveableItems {
$stmt->closeCursor();
$items->setTrackChanges(true);
+
return $items;
}
@@ -125,7 +128,7 @@ abstract class WireSaveableItemsLookup extends WireSaveableItems {
throw new WireException("$class::save() requires an item that implements HasLookupItems interface");
}
- $database = $this->wire('database');
+ $database = $this->wire()->database;
$lookupTable = $database->escapeTable($this->getLookupTable());
$lookupField = $database->escapeCol($this->getLookupField());
$table = $database->escapeTable($this->getTable());
@@ -141,15 +144,18 @@ abstract class WireSaveableItemsLookup extends WireSaveableItems {
$item_id = (int) $item->id; // reload, in case it was 0 before
$sort = 0;
- if($item_id) foreach($item->getLookupItems() as $key => $value) {
- $value_id = (int) $value->id;
- $query = $database->prepare("INSERT INTO $lookupTable SET {$table}_id=:item_id, $lookupField=:value_id, sort=:sort");
- $query->bindValue(":item_id", $item_id);
- $query->bindValue(":value_id", $value_id);
- $query->bindValue(":sort", $sort);
- $query->execute();
+ if($item_id) {
+ $sql = "INSERT INTO $lookupTable SET {$table}_id=:item_id, $lookupField=:value_id, sort=:sort";
+ $query = $database->prepare($sql);
+ foreach($item->getLookupItems() as $key => $value) {
+ $value_id = (int) $value->id;
+ $query->bindValue(":item_id", $item_id, \PDO::PARAM_INT);
+ $query->bindValue(":value_id", $value_id, \PDO::PARAM_INT);
+ $query->bindValue(":sort", $sort, \PDO::PARAM_INT);
+ $query->execute();
+ $sort++;
+ }
$this->resetTrackChanges();
- $sort++;
}
return $result;
@@ -163,7 +169,7 @@ abstract class WireSaveableItemsLookup extends WireSaveableItems {
*
*/
public function ___delete(Saveable $item) {
- $database = $this->wire('database');
+ $database = $this->wire()->database;
$lookupTable = $database->escapeTable($this->getLookupTable());
$table = $database->escapeTable($this->getTable());
$item_id = (int) $item->id;
diff --git a/wire/modules/Fieldtype/FieldtypePage.module b/wire/modules/Fieldtype/FieldtypePage.module
index c71bd91e..4a01d52a 100644
--- a/wire/modules/Fieldtype/FieldtypePage.module
+++ b/wire/modules/Fieldtype/FieldtypePage.module
@@ -1055,7 +1055,7 @@ class FieldtypePage extends FieldtypeMulti implements Module, ConfigurableModule
$value = date('Y-m-d H:i:s', $value);
} else if(in_array($subfield, array('template', 'templates_id'))) {
- $template = $this->templates->get($subfield);
+ $template = $this->templates->get($value);
$value = $template ? $template->id : 0;
$subfield = 'templates_id';
@@ -1235,6 +1235,9 @@ class FieldtypePage extends FieldtypeMulti implements Module, ConfigurableModule
*
*/
public function ___getSelectorInfo(Field $field, array $data = array()) {
+
+ $pages = $this->wire()->pages;
+ $templates = $this->wire()->templates;
$info = parent::___getSelectorInfo($field, $data);
if(!isset($data['level'])) $data['level'] = 0;
@@ -1245,29 +1248,34 @@ class FieldtypePage extends FieldtypeMulti implements Module, ConfigurableModule
$fieldgroups = array();
$template_ids = self::getTemplateIDs($field);
$parent_id = $field->get('parent_id');
+ $templateOptions = array();
if($template_ids) {
// determine fieldgroup(s) from template setting
// template_id can be int or array of ints
foreach($template_ids as $tid) {
- $template = $this->wire('templates')->get((int) $tid);
- if($template) $fieldgroups[] = $template->fieldgroup;
+ $template = $templates->get((int) $tid);
+ if(!$template) continue;
+ $fieldgroups[] = $template->fieldgroup;
+ $templateOptions[$template->id] = $template->getLabel();
}
} else if($parent_id) {
// determine fieldgroup(s) from family settings
- $parent = $this->wire('pages')->get((int) $parent_id);
+ $parent = $pages->get((int) $parent_id);
if($parent->id) {
foreach($parent->template->childTemplates as $template_id) {
- $template = $this->wire('templates')->get((int) $template_id);
+ $template = $templates->get((int) $template_id);
if(!$template) continue;
$fieldgroups[$template->fieldgroup->id] = $template->fieldgroup;
+ $templateOptions[$template->id] = $template->getLabel();
}
- foreach($this->wire('templates') as $template) {
+ foreach($templates as $template) {
if(!in_array($parent->template->id, $template->parentTemplates)) continue;
- if(!$this->wire('pages')->count("parent=$parent_id, template=$template->id, include=all")) continue;
- $fieldgroups[$template->fieldgroup->id] = $template->fieldgroup;
+ if(!$pages->count("parent=$parent_id, template=$template->id, include=all")) continue;
+ $fieldgroups[$template->fieldgroup->id] = $template->fieldgroup;
+ $templateOptions[$template->id] = $template->getLabel();
}
}
}
@@ -1276,6 +1284,12 @@ class FieldtypePage extends FieldtypeMulti implements Module, ConfigurableModule
// if no fieldgorups found, then we have no choice but to use all fields
//$fieldgroups[] = $this->wire('fields');
}
+
+ if(!count($templateOptions)) {
+ foreach($templates as $template) {
+ $templateOptions[$template->id] = $template->getLabel();
+ }
+ }
foreach($fieldgroups as $fieldgroup) {
foreach($fieldgroup as $f) {
@@ -1290,7 +1304,14 @@ class FieldtypePage extends FieldtypeMulti implements Module, ConfigurableModule
'name' => 'count',
'label' => $this->_('Count'), // Label for 'count' property of a PageArray
'input' => 'number',
- );
+ );
+
+ $subfields['templates_id'] = array(
+ 'name' => 'templates_id',
+ 'label' => $this->_('Template'), // Label for 'template' property of a Page
+ 'input' => 'select',
+ 'options' => $templateOptions,
+ );
$info['subfields'] = $subfields;
diff --git a/wire/modules/Jquery/JqueryUI/modal.js b/wire/modules/Jquery/JqueryUI/modal.js
index a966e5b1..8c1e8bd7 100644
--- a/wire/modules/Jquery/JqueryUI/modal.js
+++ b/wire/modules/Jquery/JqueryUI/modal.js
@@ -270,7 +270,7 @@ function pwModalWindow(href, options, size) {
$iframe.refresh();
};
$iframe.setTitle = function(title) {
- $iframe.dialog('option', 'title', title);
+ $iframe.dialog('option', 'title', jQuery('').text(title).html());
};
return $iframe;
diff --git a/wire/modules/Jquery/JqueryUI/modal.min.js b/wire/modules/Jquery/JqueryUI/modal.min.js
index e41cc0a4..5a401e06 100644
--- a/wire/modules/Jquery/JqueryUI/modal.min.js
+++ b/wire/modules/Jquery/JqueryUI/modal.min.js
@@ -1 +1 @@
-var pwModalWindows=[];function pwModalWindowSettings(name){var modal=ProcessWire.config.modals[name];if(typeof modal=="undefined")modal=ProcessWire.config.modals["medium"];modal=modal.split(",");var options={modal:true,draggable:false,resizable:true,hide:250,show:100,hideOverflow:true,closeOnEscape:false};if(modal.length>=4){for(var n=4;n").find(".ui-icon").remove();if(frameElement){if(typeof parent.jQuery!=="undefined"){if(parent.jQuery(".ui-dialog").length){parent.jQuery(".ui-dialog .ui-button").addClass("pw-modal-hidden").hide();parent.jQuery(".ui-dialog-buttonpane").css("margin-top","-10px");jQuery("body").css("overflow","hidden")}}else{if(parent.document.querySelector(".ui-dialog")){var parentButtons=parent.document.querySelectorAll(".ui-dialog .ui-button");var i;for(i=0;i0){url=href}else{url=href+(href.indexOf("?")>-1?"&":"?")+"modal=1"}$iframe=jQuery('');$iframe.attr("id","pw-modal-window-"+(pwModalWindows.length+1));pwModalWindows[pwModalWindows.length]=$iframe;if(typeof size=="undefined"||size.length==0)size="large";var settings=pwModalWindowSettings(size);if(settings==null){alert("Unknown modal setting: "+size);return $iframe}if(typeof options!="undefined")jQuery.extend(settings,options);$iframe.on("dialogopen",function(event,ui){jQuery(document).trigger("pw-modal-opened",{event:event,ui:ui})});$iframe.on("dialogclose",function(event,ui){jQuery(document).trigger("pw-modal-closed",{event:event,ui:ui})});$iframe.dialog(settings);$iframe.data("settings",settings);$iframe.load(function(){if(typeof settings.title=="undefined"||!settings.title){var title=jQuery("").text($iframe.contents().find("title").text()).html();$iframe.dialog("option","title",title)}$iframe.contents().find("form").css("-webkit-backface-visibility","hidden")});var lastWidth=0;var lastHeight=0;function updateWindowSize(){var width=jQuery(window).width();var height=jQuery(window).height();if(width==lastWidth&&height==lastHeight||!$iframe.hasClass("ui-dialog-content"))return;var _size=size;if(width<=960&&size!="full"&&size!="large")_size="large";if(width<=700&&size!="full")_size="full";var _settings=pwModalWindowSettings(_size);var $dialog=$iframe.closest(".ui-dialog");if($dialog.length>0){var subtractHeight=$dialog.find(".ui-dialog-buttonpane").outerHeight()+$dialog.find(".ui-dialog-titlebar").outerHeight();_settings.height-=subtractHeight}$iframe.dialog("option","width",_settings.width);$iframe.dialog("option","height",_settings.height);$iframe.dialog("option","position",_settings.position);$iframe.width(_settings.width).height(_settings.height);lastWidth=width;lastHeight=height}updateWindowSize();jQuery(window).resize(updateWindowSize);$iframe.refresh=function(){lastWidth=0;lastHeight=0;updateWindowSize()};$iframe.setButtons=function(buttons){$iframe.dialog("option","buttons",buttons);$iframe.refresh()};$iframe.setTitle=function(title){$iframe.dialog("option","title",title)};return $iframe}function pwModalOpenEvent(e){var $a=jQuery(this);var _autoclose=$a.attr("data-autoclose");var autoclose=_autoclose!=null;var autocloseSelector=autoclose&&_autoclose.length>1?_autoclose:"";var closeSelector=$a.attr("data-close");var closeOnLoad=false;var modalSize="medium";if($a.hasClass("pw-modal-large"))modalSize="large";else if($a.hasClass("pw-modal-small"))modalSize="small";else if($a.hasClass("pw-modal-full"))modalSize="full";var settings={title:$a.attr("title"),close:function(e,ui){var abort=typeof e.originalEvent!="undefined"&&jQuery(e.originalEvent.target).closest(".ui-dialog-titlebar-close").length>0;var eventData={event:e,ui:ui,abort:abort};$a.trigger("modal-close",eventData);$a.trigger("pw-modal-closed",eventData);jQuery(document).trigger("pw-modal-closed",eventData);$spinner.remove()}};var buttonSelector=$a.attr("data-buttons");if(closeSelector==null)closeSelector="";closeSelector+=(closeSelector.length>0?", ":"")+".pw-modal-cancel";var $spinner=jQuery("").css({position:"absolute",top:parseInt(jQuery(window).height()/2)-80+"px",left:parseInt(jQuery(window).width()/2)-20+"px","z-index":9999}).hide();var href=$a.attr("data-pw-modal-href");if(href&&href.length){}else if($a.is("button")){var $aparent=$a.closest("a");href=$aparent.length?$aparent.attr("href"):$a.attr("data-href");if(!href)href=$a.find("a").attr("href")}else if($a.is("a")){href=$a.attr("href")}else{href=$a.attr("data-href")}if(!href){alert("Unable to find href attribute for: "+$a.text());return false}var $iframe=pwModalWindow(href,settings,modalSize);jQuery("body").append($spinner.fadeIn("fast"));setTimeout(function(){$a.removeClass("ui-state-active")},500);$iframe.load(function(){var buttons=[];var $icontents=$iframe.contents();var n=0;$spinner.fadeOut("fast",function(){$spinner.remove()});if(closeOnLoad){var $errorItems=$icontents.find(".NoticeError, .ui-state-error");if($errorItems.length==0){if(typeof Notifications!="undefined"){var messages=[];$icontents.find(".NoticeMessage").each(function(){messages[messages.length]=jQuery(this).text()});if(messages.length>0)setTimeout(function(){for(var i=0;i0&&$button.is(closeSelector)){$iframe.dialog("close")}if(autoclose){jQuery("body").append($spinner.fadeIn());if(autocloseSelector.length>1){closeOnLoad=$button.is(autocloseSelector)}else{closeOnLoad=true}}}};n++}if(!$button.hasClass("pw-modal-button-visible"))$button.hide()})}if(buttons.length>0)$iframe.setButtons(buttons);$body.fadeIn("fast",function(){$body.show()})});return false}(function($){$.event.special.pwdoubletap={bindType:"touchend",delegateType:"touchend",handle:function(event){var handleObj=event.handleObj,targetData=jQuery.data(event.target),now=(new Date).getTime(),delta=targetData.lastTouch?now-targetData.lastTouch:0,delay=delay==null?300:delay;if(delta30){targetData.lastTouch=null;event.type=handleObj.origType;["clientX","clientY","pageX","pageY"].forEach(function(property){event[property]=event.originalEvent.changedTouches[0][property]});handleObj.handler.apply(this,arguments)}else{targetData.lastTouch=now}}}})(jQuery);function pwModalDoubleClick(){var clicks=0,timer=null,allowClick=false;jQuery(document).on("click",".pw-modal-dblclick a",function(){var $a=jQuery(this);if(allowClick){allowClick=false;return true}clicks++;if(clicks===1){timer=setTimeout(function(){clicks=0;allowClick=true;$a[0].click();return true},700)}else{clearTimeout(timer);allowClick=false;clicks=0;jQuery(this).closest(".pw-modal-dblclick").trigger("dblclick")}return false});jQuery(document).on("dblclick",".pw-modal-dblclick a",function(e){e.stopPropagation();return false});var isTouch="ontouchstart"in window||navigator.MaxTouchPoints>0||navigator.msMaxTouchPoints>0;if(isTouch){jQuery(document).on("pwdoubletap",".pw-modal-dblclick",pwModalOpenEvent)}}jQuery(document).ready(function($){$.widget("ui.dialog",$.extend({},$.ui.dialog.prototype,{_title:function(title){if(!this.options.title){title.html(" ")}else{title.html(this.options.title)}}}));$(document).on("pwdblclick",".pw-modal-dblclick",pwModalOpenEvent);$(document).on("click",".pw-modal:not(.pw-modal-dblclick):not(.pw-modal-longclick)",pwModalOpenEvent);$(document).on("dblclick",".pw-modal-dblclick",pwModalOpenEvent);$(document).on("longclick",".pw-modal-longclick",pwModalOpenEvent);pwModalDoubleClick()});
\ No newline at end of file
+var pwModalWindows=[];function pwModalWindowSettings(name){var modal=ProcessWire.config.modals[name];if(typeof modal=="undefined")modal=ProcessWire.config.modals["medium"];modal=modal.split(",");var options={modal:true,draggable:false,resizable:true,hide:250,show:100,hideOverflow:true,closeOnEscape:false};if(modal.length>=4){for(var n=4;n").find(".ui-icon").remove();if(frameElement){if(typeof parent.jQuery!=="undefined"){if(parent.jQuery(".ui-dialog").length){parent.jQuery(".ui-dialog .ui-button").addClass("pw-modal-hidden").hide();parent.jQuery(".ui-dialog-buttonpane").css("margin-top","-10px");jQuery("body").css("overflow","hidden")}}else{if(parent.document.querySelector(".ui-dialog")){var parentButtons=parent.document.querySelectorAll(".ui-dialog .ui-button");var i;for(i=0;i0){url=href}else{url=href+(href.indexOf("?")>-1?"&":"?")+"modal=1"}$iframe=jQuery('');$iframe.attr("id","pw-modal-window-"+(pwModalWindows.length+1));pwModalWindows[pwModalWindows.length]=$iframe;if(typeof size=="undefined"||size.length==0)size="large";var settings=pwModalWindowSettings(size);if(settings==null){alert("Unknown modal setting: "+size);return $iframe}if(typeof options!="undefined")jQuery.extend(settings,options);$iframe.on("dialogopen",function(event,ui){jQuery(document).trigger("pw-modal-opened",{event:event,ui:ui})});$iframe.on("dialogclose",function(event,ui){jQuery(document).trigger("pw-modal-closed",{event:event,ui:ui})});$iframe.dialog(settings);$iframe.data("settings",settings);$iframe.load(function(){if(typeof settings.title=="undefined"||!settings.title){var title=jQuery("").text($iframe.contents().find("title").text()).html();$iframe.dialog("option","title",title)}$iframe.contents().find("form").css("-webkit-backface-visibility","hidden")});var lastWidth=0;var lastHeight=0;function updateWindowSize(){var width=jQuery(window).width();var height=jQuery(window).height();if(width==lastWidth&&height==lastHeight||!$iframe.hasClass("ui-dialog-content"))return;var _size=size;if(width<=960&&size!="full"&&size!="large")_size="large";if(width<=700&&size!="full")_size="full";var _settings=pwModalWindowSettings(_size);var $dialog=$iframe.closest(".ui-dialog");if($dialog.length>0){var subtractHeight=$dialog.find(".ui-dialog-buttonpane").outerHeight()+$dialog.find(".ui-dialog-titlebar").outerHeight();_settings.height-=subtractHeight}$iframe.dialog("option","width",_settings.width);$iframe.dialog("option","height",_settings.height);$iframe.dialog("option","position",_settings.position);$iframe.width(_settings.width).height(_settings.height);lastWidth=width;lastHeight=height}updateWindowSize();jQuery(window).resize(updateWindowSize);$iframe.refresh=function(){lastWidth=0;lastHeight=0;updateWindowSize()};$iframe.setButtons=function(buttons){$iframe.dialog("option","buttons",buttons);$iframe.refresh()};$iframe.setTitle=function(title){$iframe.dialog("option","title",jQuery("").text(title).html())};return $iframe}function pwModalOpenEvent(e){var $a=jQuery(this);var _autoclose=$a.attr("data-autoclose");var autoclose=_autoclose!=null;var autocloseSelector=autoclose&&_autoclose.length>1?_autoclose:"";var closeSelector=$a.attr("data-close");var closeOnLoad=false;var modalSize="medium";if($a.hasClass("pw-modal-large"))modalSize="large";else if($a.hasClass("pw-modal-small"))modalSize="small";else if($a.hasClass("pw-modal-full"))modalSize="full";var settings={title:$a.attr("title"),close:function(e,ui){var abort=typeof e.originalEvent!="undefined"&&jQuery(e.originalEvent.target).closest(".ui-dialog-titlebar-close").length>0;var eventData={event:e,ui:ui,abort:abort};$a.trigger("modal-close",eventData);$a.trigger("pw-modal-closed",eventData);jQuery(document).trigger("pw-modal-closed",eventData);$spinner.remove()}};var buttonSelector=$a.attr("data-buttons");if(closeSelector==null)closeSelector="";closeSelector+=(closeSelector.length>0?", ":"")+".pw-modal-cancel";var $spinner=jQuery("").css({position:"absolute",top:parseInt(jQuery(window).height()/2)-80+"px",left:parseInt(jQuery(window).width()/2)-20+"px","z-index":9999}).hide();var href=$a.attr("data-pw-modal-href");if(href&&href.length){}else if($a.is("button")){var $aparent=$a.closest("a");href=$aparent.length?$aparent.attr("href"):$a.attr("data-href");if(!href)href=$a.find("a").attr("href")}else if($a.is("a")){href=$a.attr("href")}else{href=$a.attr("data-href")}if(!href){alert("Unable to find href attribute for: "+$a.text());return false}var $iframe=pwModalWindow(href,settings,modalSize);jQuery("body").append($spinner.fadeIn("fast"));setTimeout(function(){$a.removeClass("ui-state-active")},500);$iframe.load(function(){var buttons=[];var $icontents=$iframe.contents();var n=0;$spinner.fadeOut("fast",function(){$spinner.remove()});if(closeOnLoad){var $errorItems=$icontents.find(".NoticeError, .ui-state-error");if($errorItems.length==0){if(typeof Notifications!="undefined"){var messages=[];$icontents.find(".NoticeMessage").each(function(){messages[messages.length]=jQuery(this).text()});if(messages.length>0)setTimeout(function(){for(var i=0;i0&&$button.is(closeSelector)){$iframe.dialog("close")}if(autoclose){jQuery("body").append($spinner.fadeIn());if(autocloseSelector.length>1){closeOnLoad=$button.is(autocloseSelector)}else{closeOnLoad=true}}}};n++}if(!$button.hasClass("pw-modal-button-visible"))$button.hide()})}if(buttons.length>0)$iframe.setButtons(buttons);$body.fadeIn("fast",function(){$body.show()})});return false}(function($){$.event.special.pwdoubletap={bindType:"touchend",delegateType:"touchend",handle:function(event){var handleObj=event.handleObj,targetData=jQuery.data(event.target),now=(new Date).getTime(),delta=targetData.lastTouch?now-targetData.lastTouch:0,delay=delay==null?300:delay;if(delta30){targetData.lastTouch=null;event.type=handleObj.origType;["clientX","clientY","pageX","pageY"].forEach(function(property){event[property]=event.originalEvent.changedTouches[0][property]});handleObj.handler.apply(this,arguments)}else{targetData.lastTouch=now}}}})(jQuery);function pwModalDoubleClick(){var clicks=0,timer=null,allowClick=false;jQuery(document).on("click",".pw-modal-dblclick a",function(){var $a=jQuery(this);if(allowClick){allowClick=false;return true}clicks++;if(clicks===1){timer=setTimeout(function(){clicks=0;allowClick=true;$a[0].click();return true},700)}else{clearTimeout(timer);allowClick=false;clicks=0;jQuery(this).closest(".pw-modal-dblclick").trigger("dblclick")}return false});jQuery(document).on("dblclick",".pw-modal-dblclick a",function(e){e.stopPropagation();return false});var isTouch="ontouchstart"in window||navigator.MaxTouchPoints>0||navigator.msMaxTouchPoints>0;if(isTouch){jQuery(document).on("pwdoubletap",".pw-modal-dblclick",pwModalOpenEvent)}}jQuery(document).ready(function($){$.widget("ui.dialog",$.extend({},$.ui.dialog.prototype,{_title:function(title){if(!this.options.title){title.html(" ")}else{title.html(this.options.title)}}}));$(document).on("pwdblclick",".pw-modal-dblclick",pwModalOpenEvent);$(document).on("click",".pw-modal:not(.pw-modal-dblclick):not(.pw-modal-longclick)",pwModalOpenEvent);$(document).on("dblclick",".pw-modal-dblclick",pwModalOpenEvent);$(document).on("longclick",".pw-modal-longclick",pwModalOpenEvent);pwModalDoubleClick()});
\ No newline at end of file
diff --git a/wire/modules/Process/ProcessTemplate/ProcessTemplate.module b/wire/modules/Process/ProcessTemplate/ProcessTemplate.module
index bf2c40d3..cc999e6a 100644
--- a/wire/modules/Process/ProcessTemplate/ProcessTemplate.module
+++ b/wire/modules/Process/ProcessTemplate/ProcessTemplate.module
@@ -2958,7 +2958,7 @@ class ProcessTemplate extends Process implements ConfigurableModule {
$template->noParents = 1;
$template->parentTemplates = array();
} else {
- $template->noParents = 0;
+ if($template->noParents != 0) $template->noParents = 0;
}
$sortfield = $sanitizer->name($input->post('sortfield'));