From 120de7cba2e1c45bf5f1e753d655c27c2cae1784 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Tue, 17 Jul 2012 15:04:27 +0200 Subject: [PATCH] NEW Tree node updates after save (fixes #7450, #7389) - Updates icon, badges, title, and position in hierarchy - New LeftAndMain_TreeNode API to allow rendering of single tree nodes without their hierarchy, extracted from LeftAndMain->getSiteTreeFor() - New LeftAndMain->updatetreenodes() endpoint to request updated state for one or more nodes. Triggered on demand by form refreshes. --- admin/code/LeftAndMain.php | 123 +++++++++++++-- admin/javascript/LeftAndMain.Tree.js | 220 ++++++++++++++++++--------- 2 files changed, 262 insertions(+), 81 deletions(-) diff --git a/admin/code/LeftAndMain.php b/admin/code/LeftAndMain.php index 92f2eea6ca7..b3e27aa01c8 100644 --- a/admin/code/LeftAndMain.php +++ b/admin/code/LeftAndMain.php @@ -72,6 +72,7 @@ class LeftAndMain extends Controller implements PermissionProvider { 'save', 'savetreenode', 'getsubtree', + 'updatetreenodes', 'printable', 'show', 'ping', @@ -678,16 +679,8 @@ function getSiteTreeFor($className, $rootID = null, $childrenMethod = null, $num $controller = $this; $recordController = ($this->stat('tree_class') == 'SiteTree') ? singleton('CMSPageEditController') : $this; $titleFn = function(&$child) use(&$controller, &$recordController) { - $classes = $child->CMSTreeClasses(); - if($controller->isCurrentPage($child)) $classes .= " current"; - $flags = $child->hasMethod('getStatusFlags') ? $child->getStatusFlags() : false; - if($flags) $classes .= ' ' . implode(' ', array_keys($flags)); - return "
  • ID\" data-id=\"$child->ID\" data-pagetype=\"$child->ClassName\" class=\"" . $classes . "\">" . - " " . - "Link("show"), $child->ID) . "\" title=\"" . - _t('LeftAndMain.PAGETYPE','Page type: ') . - "$child->class\" > " . ($child->TreeTitle). - ""; + $link = Controller::join_links($recordController->Link("show"), $child->ID); + return LeftAndMain_TreeNode::create($child, $link, $controller->isCurrentPage($child))->forTemplate(); }; $html = $obj->getChildrenAsUL( "", @@ -740,6 +733,32 @@ public function getsubtree($request) { return $html; } + + /** + * Allows requesting a view update on specific tree nodes. + * Similar to {@link getsubtree()}, but doesn't enforce loading + * all children with the node. Useful to refresh views after + * state modifications, e.g. saving a form. + * + * @return String JSON + */ + public function updatetreenodes($request) { + $data = array(); + $ids = explode(',', $request->getVar('ids')); + foreach($ids as $id) { + $record = $this->getRecord($id); + $recordController = ($this->stat('tree_class') == 'SiteTree') ? singleton('CMSPageEditController') : $this; + $link = Controller::join_links($recordController->Link("show"), $record->ID); + $html = LeftAndMain_TreeNode::create($record, $link, $this->isCurrentPage($record))->forTemplate() . '
  • '; + $data[$id] = array( + 'html' => $html, + 'ParentID' => $record->ParentID, + 'Sort' => $record->Sort + ); + } + $this->response->addHeader('Content-Type', 'text/json'); + return Convert::raw2json($data); + } /** * Save handler @@ -1499,3 +1518,87 @@ function setIsFinished($bool) { } } + +/** + * Wrapper around objects being displayed in a tree. + * Caution: Volatile API. + * + * @todo Implement recursive tree node rendering + */ +class LeftAndMain_TreeNode extends ViewableData { + + /** + * @var obj + */ + protected $obj; + + /** + * @var String Edit link to the current record in the CMS + */ + protected $link; + + /** + * @var Bool + */ + protected $isCurrent; + + function __construct($obj, $link = null, $isCurrent = false) { + $this->obj = $obj; + $this->link = $link; + $this->isCurrent = $isCurrent; + } + + /** + * Returns template, for further processing by {@link Hierarchy->getChildrenAsUL()}. + * Does not include closing tag to allow this method to inject its own children. + * + * @todo Remove hardcoded assumptions around returning an
  • , by implementing recursive tree node rendering + * + * @return String + */ + function forTemplate() { + $obj = $this->obj; + return "
  • ID\" data-id=\"$obj->ID\" data-pagetype=\"$obj->ClassName\" class=\"" . $this->getClasses() . "\">" . + " " . + "getLink() . "\" title=\"" . + _t('LeftAndMain.PAGETYPE','Page type: ') . + "$obj->class\" > " . ($obj->TreeTitle). + ""; + } + + function getClasses() { + $classes = $this->obj->CMSTreeClasses(); + if($this->isCurrent) $classes .= " current"; + $flags = $this->obj->hasMethod('getStatusFlags') ? $this->obj->getStatusFlags() : false; + if($flags) $classes .= ' ' . implode(' ', array_keys($flags)); + return $classes; + } + + function getObj() { + return $this->obj; + } + + function setObj($obj) { + $this->obj = $obj; + return $this; + } + + function getLink() { + return $this->link; + } + + function setLink($link) { + $this->link = $link; + return $this; + } + + function getIsCurrent() { + return $this->isCurrent; + } + + function setIsCurrent($bool) { + $this->isCurrent = $bool; + return $this; + } + +} \ No newline at end of file diff --git a/admin/javascript/LeftAndMain.Tree.js b/admin/javascript/LeftAndMain.Tree.js index f9ffdde84a9..731d231fba8 100644 --- a/admin/javascript/LeftAndMain.Tree.js +++ b/admin/javascript/LeftAndMain.Tree.js @@ -10,6 +10,10 @@ Hints: null, + IsUpdatingTree: false, + + IsLoaded: false, + onadd: function(){ this._super(); @@ -22,7 +26,6 @@ /** * @todo Icon and page type hover support * @todo Sorting of sub nodes (originally placed in context menu) - * @todo Refresh after language