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

Attempt fix for issue processwire/processwire-issues#661 where cached PageList data could re-appear when closing then re-opening an item in the PageList. Was an issue if an item was moved or trashed, because it could appear to still be in the old location in the PageList even when it wasn't. This commit also refactors several parts in ProcessPageList.js.

This commit is contained in:
Ryan Cramer
2018-10-01 11:21:43 -04:00
parent 11cb8deaa2
commit 546340652f
3 changed files with 108 additions and 32 deletions

View File

@@ -108,7 +108,7 @@ $(document).ready(function() {
// IDs of the pages that we want to automatically open (default none) // IDs of the pages that we want to automatically open (default none)
openPageIDs: [], openPageIDs: [],
// pre-rendered data corresponding to openPageIDs, indexed by '_123' where 123 is id // pre-rendered data corresponding to openPageIDs, indexed by 'id-start', i.e. 123-0
openPageData: {}, openPageData: {},
// speed at which the slideUp/slideDown run (in ms) // speed at which the slideUp/slideDown run (in ms)
@@ -511,6 +511,8 @@ $(document).ready(function() {
var nextStart = data.start + data.limit; var nextStart = data.start + data.limit;
//var openPageKey = id + '-' + start; //var openPageKey = id + '-' + start;
if($target.hasClass('PageListItem')) setNumChildren($target, data.page.numChildren);
if(data.page.numChildren > nextStart) { if(data.page.numChildren > nextStart) {
var $a = $("<a></a>").attr('href', nextStart).data('pageId', id).text(options.moreLabel).click(clickMore); var $a = $("<a></a>").attr('href', nextStart).data('pageId', id).text(options.moreLabel).click(clickMore);
$children.append($("<ul></ul>").addClass('PageListActions actions').append($("<li></li>").addClass('PageListActionMore').append($a))); $children.append($("<ul></ul>").addClass('PageListActions actions').append($("<li></li>").addClass('PageListActionMore').append($a)));
@@ -572,8 +574,6 @@ $(document).ready(function() {
} }
} }
*/ */
$target.removeClass('PageListForceReload'); // if it happens to be present
}; };
if(!replace) $target.append($loading.fadeIn('fast')); if(!replace) $target.append($loading.fadeIn('fast'));
@@ -628,6 +628,46 @@ $(document).ready(function() {
return $list; return $list;
} }
/**
* Set a parent to reload its children on next access rather than using cached data
*
* @param $pageListItem .PageList or .PageListItem element
* @param reloadNow Reload the list now? (default=false)
*
*/
function setForceReload($pageListItem, reloadNow) {
if($pageListItem.hasClass('PageList')) $pageListItem = $pageListItem.prev('.PageListItem');
$pageListItem.addClass('PageListForceReload');
var id = $pageListItem.data('pageId');
var prefix = id + '-';
if(typeof options.openPageData != "undefined") {
// remove cached items from openPageData
var openPageData = {};
for(var key in options.openPageData) {
if(key.indexOf(prefix) === 0) {
// skip it
} else {
openPageData[key] = options.openPageData[key];
}
}
options.openPageData = openPageData;
}
if(typeof reloadNow != "undefined" && reloadNow) {
var $a = $pageListItem.children('a.PageListPage');
if($pageListItem.hasClass('PageListItemOpen')) {
$a.click();
setTimeout(function() { $a.click(); }, 250);
} else {
$a.click();
}
}
}
/** /**
* *
* @param $ul Any element that contains items needing click events attached * @param $ul Any element that contains items needing click events attached
@@ -750,6 +790,36 @@ $(document).ready(function() {
return $li; return $li;
} }
/**
* Get number of children for given .PageListItem
*
*/
function getNumChildren($item) {
var $numChildren = $item.children('.PageListNumChildren');
if(!$numChildren.length) return 0;
var numChildren = $numChildren.text();
return numChildren.length ? parseInt(numChildren) : 0;
}
/**
* Set number of children for given PageListItem
*
*/
function setNumChildren($item, numChildren) {
var $numChildren = $item.children('.PageListNumChildren');
if(!$numChildren.length) {
$numChildren = $('<span>0</span>').addClass('PageListNumChildren detail');
$item.append($numChildren);
}
if(numChildren < 1) {
$item.removeClass('PageListHasChildren').addClass('PageListNoChildren');
numChildren = '';
} else {
$item.removeClass('PageListNoChildren').addClass('PageListHasChildren');
}
$numChildren.text(numChildren);
}
/** /**
* Extra actions button click handler * Extra actions button click handler
* *
@@ -852,6 +922,7 @@ $(document).ready(function() {
$liNew.hide(); $liNew.hide();
$li.after($liNew); $li.after($liNew);
$liNew.slideDown(); $liNew.slideDown();
setForceReload($liNew.closest('.PageList'));
} else if($liNew) { } else if($liNew) {
// update existing item // update existing item
if($li.hasClass('PageListItemOpen')) $liNew.addClass('PageListItemOpen'); if($li.hasClass('PageListItemOpen')) $liNew.addClass('PageListItemOpen');
@@ -862,12 +933,16 @@ $(document).ready(function() {
// display message for 1 second, then remove // display message for 1 second, then remove
setTimeout(function () { setTimeout(function () {
$msg.fadeOut('normal', function () { $msg.fadeOut('normal', function () {
var $parentItem = $liNew.closest('.PageList').prev('.PageListItem');
var numChildren = getNumChildren($parentItem);
if(removeItem) { if(removeItem) {
var $numChildren = $liNew.closest('.PageList').prev('.PageListItem').children('.PageListNumChildren'); numChildren--;
if($numChildren.length) { } else if(addNew) {
var numChildren = parseInt($numChildren.text()); numChildren++;
if(numChildren > 0) $numChildren.text(numChildren-1);
} }
setNumChildren($parentItem, numChildren);
setForceReload($parentItem);
if(removeItem) {
$liNew.next('.PageList').fadeOut('fast'); $liNew.next('.PageList').fadeOut('fast');
$liNew.fadeOut('fast', function() { $liNew.fadeOut('fast', function() {
$liNew.remove(); $liNew.remove();
@@ -882,16 +957,7 @@ $(document).ready(function() {
// refresh the children of the page represented by refreshChildren // refresh the children of the page represented by refreshChildren
if(refreshChildren) { if(refreshChildren) {
var $refreshParent = $(".PageListID" + refreshChildren); var $refreshParent = $(".PageListID" + refreshChildren);
if($refreshParent.length) { if($refreshParent.length) setForceReload($refreshParent, true);
$refreshParent.addClass('PageListForceReload');
var $a = $refreshParent.children('a.PageListPage');
if($refreshParent.hasClass('PageListItemOpen')) {
$a.click();
setTimeout(function() { $a.click(); }, 250);
} else {
$a.click();
}
}
} }
}); });
@@ -1052,7 +1118,7 @@ $(document).ready(function() {
$removeItems = $parentList.children(); $removeItems = $parentList.children();
$parentList = $parentItem; $parentList = $parentItem;
} }
$parentList.addClass('PageListForceReload'); setForceReload($parentList);
loadChildren(parentID, $parentList, start, false, true, true, function() { loadChildren(parentID, $parentList, start, false, true, true, function() {
if($removeItems && $removeItems.length) $removeItems.remove(); if($removeItems && $removeItems.length) $removeItems.remove();
}); });
@@ -1105,7 +1171,7 @@ $(document).ready(function() {
$root.find('.PageListItemOpen').each(function() { $root.find('.PageListItemOpen').each(function() {
var numChildren = $(this).children('.PageListNumChildren').text(); var numChildren = $(this).children('.PageListNumChildren').text();
// if there are children and the next sibling doesn't contain a visible .PageList, then don't add a placeholder // if there are children and the next sibling doesn't contain a visible .PageList, then don't add a placeholder
if(parseInt(numChildren) > 1 && $(this).next().find(".PageList:visible").size() == 0) { if(parseInt(numChildren) > 1 && $(this).next().find(".PageList:visible").length == 0) {
return; return;
} }
var $ul = $("<div></div>").addClass('PageListPlaceholder').addClass('PageList'); var $ul = $("<div></div>").addClass('PageListPlaceholder').addClass('PageList');
@@ -1209,15 +1275,22 @@ $(document).ready(function() {
var parent_id = parseInt($ulPrev.data('pageId')); var parent_id = parseInt($ulPrev.data('pageId'));
// check if item was moved to an invalid spot // check if item was moved to an invalid spot
// in this case, a spot between another open PageListItem and it's PageList // in this case, a spot between another open PageListItem and its PageList
var $liPrev = $li.prev(".PageListItem"); var $liPrev = $li.prev(".PageListItem");
if($liPrev.is(".PageListItemOpen")) return false; if($liPrev.is(".PageListItemOpen")) return false;
// check if item was moved into an invisible parent placeholder PageList // check if item was moved into an invisible parent placeholder PageList
if($ul.is('.PageListPlaceholder')) { if($ul.is('.PageListPlaceholder')) {
var $ulNext = $ul.next();
if($ulNext.is('.PageList:visible')) {
// first item at top of list ended up in placeholder, but belongs in next sibling PageList
$ulNext.prepend($li);
$ul = $ulNext;
} else {
// if so, it's no longer a placeholder, but a real PageList // if so, it's no longer a placeholder, but a real PageList
$ul.removeClass('PageListPlaceholder').children('.PageListPlaceholderItem').remove(); $ul.removeClass('PageListPlaceholder').children('.PageListPlaceholderItem').remove();
} }
}
$root.addClass('PageListSortSaving'); $root.addClass('PageListSortSaving');
cancelMove($li); cancelMove($li);
@@ -1267,14 +1340,16 @@ $(document).ready(function() {
$from.remove(); // empty list, no longer needed $from.remove(); // empty list, no longer needed
} }
$numChildren.text(n); $numChildren.text(n);
setForceReload($fromItem);
// update count where item went to // update count where item went to
var $toItem = $ul.prev(".PageListItem"); var $toItem = $ul.prev(".PageListItem");
$numChildren = $toItem.children(".PageListNumChildren"); $numChildren = $toItem.children(".PageListNumChildren");
n = $numChildren.text().length > 0 ? parseInt($numChildren.text()) + 1 : 1; n = $numChildren.text().length > 0 ? parseInt($numChildren.text()) + 1 : 1;
$numChildren.text(n); $numChildren.text(n);
setForceReload($toItem);
} }
$from.attr('id', ''); $from.attr('id', ''); // remove tempoary #PageListMoveFrom
$root.removeClass('PageListSortSaving'); $root.removeClass('PageListSortSaving');
}, 'json'); }, 'json');

File diff suppressed because one or more lines are too long

View File

@@ -38,7 +38,7 @@ class ProcessPageList extends Process implements ConfigurableModule {
return array( return array(
'title' => 'Page List', 'title' => 'Page List',
'summary' => 'List pages in a hierarchal tree structure', 'summary' => 'List pages in a hierarchal tree structure',
'version' => 121, 'version' => 122,
'permanent' => true, 'permanent' => true,
'permission' => 'page-edit', 'permission' => 'page-edit',
'icon' => 'sitemap', 'icon' => 'sitemap',
@@ -133,10 +133,10 @@ class ProcessPageList extends Process implements ConfigurableModule {
$limit = (int) $input->get->int('limit'); $limit = (int) $input->get->int('limit');
$render = $input->get('render'); $render = $input->get('render');
$this->start = (int) $input->get->int('start'); //isset($_GET['start']) ? (int) $_GET['start'] : 0; $this->start = (int) $input->get->int('start'); //isset($_GET['start']) ? (int) $_GET['start'] : 0;
$this->limit = $limit && $limit < $this->limit ? $limit : $this->limit; $this->limit = $limit > 0 && $limit < $this->limit ? $limit : $this->limit;
$this->render = $render ? strtoupper($this->wire('sanitizer')->name($render)) : ''; $this->render = $render ? strtoupper($this->wire('sanitizer')->name($render)) : '';
if($isAjax && !$this->render && !$input->get('renderInputfieldAjax')) $this->render = 'JSON'; if($isAjax && !$this->render && !$input->get('renderInputfieldAjax')) $this->render = 'JSON';
if($this->render && !isset($this->allowRenderTypes[$this->render])) $this->render = null; if(strlen($this->render) && !isset($this->allowRenderTypes[$this->render])) $this->render = null;
$settings = $config->pageList; $settings = $config->pageList;
if(is_array($settings)) { if(is_array($settings)) {
@@ -332,7 +332,8 @@ class ProcessPageList extends Process implements ConfigurableModule {
protected function getPageListRender(Page $page, $limit = null, $start = null) { protected function getPageListRender(Page $page, $limit = null, $start = null) {
require_once(dirname(__FILE__) . '/ProcessPageListRender.php'); require_once(dirname(__FILE__) . '/ProcessPageListRender.php');
$class = "ProcessPageListRender" . $this->render; if(!$this->render || !isset($this->allowRenderTypes[$this->render])) $this->render = 'JSON';
$class = $this->allowRenderTypes[$this->render];
$className = wireClassName($class, true); $className = wireClassName($class, true);
if(!class_exists($className, false)) require_once(dirname(__FILE__) . "/$class.php"); if(!class_exists($className, false)) require_once(dirname(__FILE__) . "/$class.php");