[Common UI] Generalize ToggleController

Add a general-purpose ToggleController for things that
need to expand and contract. WTD-574.
This commit is contained in:
Victor Woeltjen
2014-11-24 07:49:50 -08:00
parent 845c1ad7d7
commit 2ab3f5f5f9
7 changed files with 86 additions and 56 deletions

View File

@@ -29,8 +29,8 @@
"depends": [ "$scope" ] "depends": [ "$scope" ]
}, },
{ {
"key": "AccordionController", "key": "ToggleController",
"implementation": "AccordionController.js" "implementation": "ToggleController.js"
}, },
{ {
"key": "ContextMenuController", "key": "ContextMenuController",

View File

@@ -1,9 +1,9 @@
<div class="accordion" ng-controller="AccordionController as accordion"> <div class="accordion" ng-controller="ToggleController as toggle">
<div class="accordion-head" ng-click="accordion.toggle()"> <div class="accordion-head" ng-click="toggle.toggle()">
{{container.title}} {{container.title}}
</div> </div>
<div class="accordion-contents" <div class="accordion-contents"
ng-show="accordion.expanded()" ng-show="toggle.isActive()"
style="height: 180px;" style="height: 180px;"
ng-transclude> ng-transclude>
</div> </div>

View File

@@ -1,7 +1,9 @@
<span ng-controller="TreeNodeController"> <span ng-controller="ToggleController as toggle">
<span class="tree-item menus-to-left"> <span class="tree-item menus-to-left" ng-controller="TreeNodeController">
<span class='ui-symbol view-control' ng-click="toggle()" ng-if="model.composition !== undefined"> <span class='ui-symbol view-control'
{{node.expanded ? "v" : ">"}} ng-click="toggle.toggle()"
ng-if="model.composition !== undefined">
{{toggle.isActive() ? "v" : ">"}}
</span> </span>
<mct-representation key="'label'" <mct-representation key="'label'"
mct-object="domainObject" mct-object="domainObject"
@@ -10,7 +12,9 @@
ng-class="{selected: node.isSelected}"> ng-class="{selected: node.isSelected}">
</mct-representation> </mct-representation>
</span> </span>
<span class="tree-item-subtree" ng-show="node.expanded" ng-if="model.composition !== undefined"> <span class="tree-item-subtree"
ng-show="toggle.isActive()"
ng-if="model.composition !== undefined">
<mct-representation key="'tree'" <mct-representation key="'tree'"
parameters="parameters" parameters="parameters"
mct-object="node.domainObject"> mct-object="node.domainObject">

View File

@@ -1,29 +0,0 @@
/*global define,Promise*/
/**
* Module defining AccordionController. Created by vwoeltje on 11/14/14.
*/
define(
[],
function () {
"use strict";
/**
*
* @constructor
*/
function AccordionController() {
var isExpanded = true;
return {
toggle: function () {
isExpanded = !isExpanded;
},
expanded: function () {
return isExpanded;
}
};
}
return AccordionController;
}
);

View File

@@ -38,7 +38,7 @@ define(
function updateGroups() { function updateGroups() {
var actionCapability = $scope.action, var actionCapability = $scope.action,
params = $scope.parameters ? $scope.parameters : {}, params = $scope.parameters || {},
category = params.category; category = params.category;
if (actionCapability && category) { if (actionCapability && category) {

View File

@@ -0,0 +1,45 @@
/*global define,Promise*/
define(
[],
function () {
"use strict";
/**
* A ToggleController is used to activate/deactivate things.
* A common usage is for "twistie"
*
* @constructor
*/
function ToggleController() {
var state = false;
return {
/**
* Get the current state of the toggle.
* @return {boolean} true if active
*/
isActive: function () {
return state;
},
/**
* Set a new state for the toggle.
* @return {boolean} true to activate
*/
setState: function (newState) {
state = newState;
},
/**
* Toggle the current state; activate if it is inactive,
* deactivate if it is active.
*/
toggle: function () {
state = !state;
}
};
}
return ToggleController;
}
);

View File

@@ -29,6 +29,15 @@ define(
return obj.getId(); return obj.getId();
} }
// Verify that id paths are equivalent, staring at
// index, ending at the end of the node path.
function checkPath(nodePath, navPath, index) {
index = index || 0;
return index > nodePath.length ||
(navPath[index] === nodePath[index] &&
checkPath(nodePath, navPath, index + 1));
}
function isOnNavigationPath(nodeObject, navObject) { function isOnNavigationPath(nodeObject, navObject) {
var nodeContext = nodeObject && var nodeContext = nodeObject &&
nodeObject.getCapability('context'), nodeObject.getCapability('context'),
@@ -41,12 +50,7 @@ define(
nodePath = nodeContext.getPath().map(getId); nodePath = nodeContext.getPath().map(getId);
navPath = navContext.getPath().map(getId); navPath = navContext.getPath().map(getId);
return (navPath.length > nodePath.length) && return (navPath.length > nodePath.length) &&
nodePath.map(function (id, i) { checkPath(nodePath, navPath);
return id === navPath[i];
}).reduce(function (a, b) {
return a && b;
}, true);
} }
return false; // No context to judge by return false; // No context to judge by
} }
@@ -58,8 +62,10 @@ define(
idsEqual(nodeObject, navigatedObject) && idsEqual(nodeObject, navigatedObject) &&
idsEqual(parentOf(nodeObject), parentOf(navigatedObject)); idsEqual(parentOf(nodeObject), parentOf(navigatedObject));
// Expand if necessary // Expand if necessary
if (!$scope.node.expanded && isOnNavigationPath(nodeObject, navigatedObject)) { if (!$scope.node.expanded &&
$scope.toggle(); isOnNavigationPath(nodeObject, navigatedObject) &&
$scope.toggle !== undefined) {
$scope.toggle.toggle();
} }
} }
@@ -68,21 +74,25 @@ define(
checkNavigation(); checkNavigation();
} }
$scope.node = { expanded: false }; // When the node is expanded, set "node.domainObject" in
// the scope; this is used to populate the subtree, which
// should only happen when first expanded (lazy loading)
function doExpand(state) {
if (state) {
$scope.node.domainObject = $scope.domainObject;
}
}
$scope.toggle = function () { // Set up a little namespace for tree node properties
var expanded = !$scope.node.expanded; $scope.node = {};
$scope.node.expanded = expanded;
// Trigger load of composition, if needed
$scope.node.domainObject = $scope.domainObject;
};
navigationService.addListener(setNavigation); navigationService.addListener(setNavigation);
$scope.$on("$destroy", function () { $scope.$on("$destroy", function () {
navigationService.removeListener(setNavigation); navigationService.removeListener(setNavigation);
}); });
$scope.$watch("domainObject", checkNavigation); $scope.$watch("domainObject", checkNavigation);
$scope.$watch("toggle.isActive()", doExpand);
} }
return TreeNodeController; return TreeNodeController;