Fixes issue with tree picker and search where the already selected nodes would be cleared when searching and not selecting anything. Adds transition to go to search.
This commit is contained in:
@@ -35,14 +35,12 @@ angular.module("umbraco.directives")
|
||||
// this will greatly improve performance since there's potentially a lot of nodes being rendered = a LOT of watches!
|
||||
|
||||
template: '<li ng-class="{\'current\': (node == currentNode)}" on-right-click="altSelect(node, $event)">' +
|
||||
'<div ng-class="{\'loading\': node.loading}" ng-swipe-right="options(node, $event)" >' +
|
||||
'<div ng-class="getNodeCssClass(node)" ng-swipe-right="options(node, $event)" >' +
|
||||
//NOTE: This ins element is used to display the search icon if the node is a container/listview and the tree is currently in dialog
|
||||
//'<ins ng-if="tree.enablelistviewsearch && node.metaData.isContainer" class="umb-tree-node-search icon-search" ng-click="searchNode(node, $event)" alt="searchAltText"></ins>' +
|
||||
'<ins style="width:18px;"></ins>' +
|
||||
'<ins ng-class="{\'icon-navigation-right\': !node.expanded, \'icon-navigation-down\': node.expanded}" ng-click="load(node)"></ins>' +
|
||||
//NOTE: If the tree supports check boxes, render different markup
|
||||
'<i ng-class="selectEnabledNodeClass(node)"></i>' +
|
||||
'<i></i>' +
|
||||
'<i class="icon umb-tree-icon sprTree"></i>' +
|
||||
'<a href ng-click="select(node, $event)" on-right-click="altSelect(node, $event)"></a>' +
|
||||
//NOTE: These are the 'option' elipses
|
||||
'<a href class="umb-options" ng-click="options(node, $event)"><i></i><i></i><i></i></a>' +
|
||||
@@ -56,25 +54,23 @@ angular.module("umbraco.directives")
|
||||
scope.searchAltText = value;
|
||||
});
|
||||
|
||||
//flag to enable/disable delete animations, default for an item is tru
|
||||
//flag to enable/disable delete animations, default for an item is true
|
||||
var deleteAnimations = true;
|
||||
|
||||
/** Helper function to emit tree events */
|
||||
// Helper function to emit tree events
|
||||
function emitEvent(eventName, args) {
|
||||
if (scope.eventhandler) {
|
||||
$(scope.eventhandler).trigger(eventName, args);
|
||||
}
|
||||
}
|
||||
|
||||
/** updates the node's DOM/styles */
|
||||
// updates the node's DOM/styles
|
||||
function setupNodeDom(node, tree) {
|
||||
|
||||
//get the first div element
|
||||
element.children(":first")
|
||||
//set the padding
|
||||
.css("padding-left", (node.level * 20) + "px")
|
||||
//set the class
|
||||
.addClass((node.cssClasses || []).join(" "));
|
||||
.css("padding-left", (node.level * 20) + "px");
|
||||
|
||||
//remove first 'ins' if there is no children
|
||||
//show/hide last 'ins' depending on children
|
||||
@@ -85,17 +81,10 @@ angular.module("umbraco.directives")
|
||||
else {
|
||||
element.find("ins").last().show();
|
||||
}
|
||||
|
||||
//add/remove 'i' depending on enablecheckboxes
|
||||
if (tree.enablecheckboxes === "true") {
|
||||
element.find("i").eq(1).remove();
|
||||
}
|
||||
else if (!tree.enablecheckboxes || tree.enablecheckboxes === 'false') {
|
||||
element.find("i:first").remove();
|
||||
element.find("i:first").addClass(node.cssClass);
|
||||
}
|
||||
//now set the title on the remaining icon
|
||||
element.find("i:first").attr("title", node.routePath);
|
||||
|
||||
var icon = element.find("i:first");
|
||||
icon.addClass(node.cssClass);
|
||||
icon.attr("title", node.routePath);
|
||||
|
||||
element.find("a:first").html(node.name);
|
||||
|
||||
@@ -108,7 +97,7 @@ angular.module("umbraco.directives")
|
||||
}
|
||||
}
|
||||
|
||||
/** This will deleteAnimations to true after the current digest */
|
||||
//This will deleteAnimations to true after the current digest
|
||||
function enableDeleteAnimations() {
|
||||
//do timeout so that it re-enables them after this digest
|
||||
$timeout(function () {
|
||||
@@ -117,12 +106,21 @@ angular.module("umbraco.directives")
|
||||
}, 0, false);
|
||||
}
|
||||
|
||||
scope.selectEnabledNodeClass = function (node) {
|
||||
return node ?
|
||||
node.selected ?
|
||||
'icon umb-tree-icon sprTree icon-check blue temporary' :
|
||||
node.cssClass :
|
||||
'';
|
||||
/** Returns the css classses assigned to the node (div element) */
|
||||
scope.getNodeCssClass = function (node) {
|
||||
if (!node) {
|
||||
return '';
|
||||
}
|
||||
var css = [];
|
||||
if (node.cssClasses) {
|
||||
_.each(node.cssClasses, function(c) {
|
||||
css.push(c);
|
||||
});
|
||||
}
|
||||
if (node.selected) {
|
||||
css.push("umb-tree-node-checked");
|
||||
}
|
||||
return css.join(" ");
|
||||
};
|
||||
|
||||
//add a method to the node which we can use to call to update the node data if we need to ,
|
||||
@@ -169,6 +167,9 @@ angular.module("umbraco.directives")
|
||||
* When changing sections we don't want all of the tree-ndoes to do their 'leave' animations.
|
||||
*/
|
||||
scope.animation = function () {
|
||||
if (scope.node.showHideAnimation) {
|
||||
return scope.node.showHideAnimation;
|
||||
}
|
||||
if (deleteAnimations && scope.node.expanded) {
|
||||
return { leave: 'tree-node-delete-leave' };
|
||||
}
|
||||
|
||||
@@ -145,3 +145,47 @@
|
||||
.tree-node-delete-leave * {
|
||||
color:@red !important;
|
||||
}
|
||||
|
||||
|
||||
.tree-node-slide-up
|
||||
{
|
||||
opacity:1;
|
||||
top: 0px;
|
||||
-webkit-transition: 700ms cubic-bezier(0.000, 0.000, 0.580, 1.000) all;
|
||||
-moz-transition: 700ms cubic-bezier(0.000, 0.000, 0.580, 1.000) all;
|
||||
-ms-transition: 700ms cubic-bezier(0.000, 0.000, 0.580, 1.000) all;
|
||||
-o-transition: 700ms cubic-bezier(0.000, 0.000, 0.580, 1.000) all;
|
||||
transition: 700ms cubic-bezier(0.000, 0.000, 0.580, 1.000) all;
|
||||
}
|
||||
.tree-node-slide-up * {
|
||||
font-size:100%;
|
||||
-webkit-transition:font-size 700ms;
|
||||
-moz-transition:font-size 700ms;
|
||||
-ms-transition:font-size 700ms;
|
||||
-o-transition:font-size 700ms;
|
||||
transition:font-size 700ms;
|
||||
}
|
||||
.tree-node-slide-up.tree-node-slide-up-hide-active {
|
||||
opacity: 0;
|
||||
top: -100px;
|
||||
}
|
||||
.tree-node-slide-up.tree-node-slide-up-hide-active * {
|
||||
font-size:120%;
|
||||
}
|
||||
|
||||
.tree-fade-out-hide ,
|
||||
.tree-fade-out-show,
|
||||
.tree-fade-out-hide div:not(.tree-node-slide-up-hide-active),
|
||||
.tree-fade-out-show div:not(.tree-node-slide-up-hide-active) {
|
||||
-webkit-transition: 700ms cubic-bezier(0.075, 0.820, 0.165, 1.000) all;
|
||||
-moz-transition: 700ms cubic-bezier(0.075, 0.820, 0.165, 1.000) all;
|
||||
-ms-transition: 700ms cubic-bezier(0.075, 0.820, 0.165, 1.000) all;
|
||||
-o-transition: 700ms cubic-bezier(0.075, 0.820, 0.165, 1.000) all;
|
||||
transition: 700ms cubic-bezier(0.075, 0.820, 0.165, 1.000) all;
|
||||
}
|
||||
.tree-fade-out-show.tree-fade-out-show-active div:not(.tree-node-slide-up-hide-active){
|
||||
opacity: 1;
|
||||
}
|
||||
.tree-fade-out-hide.tree-fade-out-hide-active div:not(.tree-node-slide-up-hide-active){
|
||||
opacity: 0;
|
||||
}
|
||||
@@ -70,13 +70,13 @@
|
||||
@import "modals.less";
|
||||
@import "panel.less";
|
||||
@import "sections.less";
|
||||
@import "helveticons.less";
|
||||
@import "main.less";
|
||||
@import "tree.less";
|
||||
@import "listview.less";
|
||||
@import "gridview.less";
|
||||
@import "footer.less";
|
||||
@import "animations.less";
|
||||
@import "helveticons.less";
|
||||
@import "dragdrop.less";
|
||||
|
||||
//used for property editors
|
||||
|
||||
@@ -150,6 +150,18 @@
|
||||
/*color:@turquoise;*/
|
||||
}
|
||||
|
||||
.icon-check:before {
|
||||
content: "\e165";
|
||||
}
|
||||
|
||||
.umb-tree .umb-tree-node-checked i {
|
||||
color:@blue !important;
|
||||
}
|
||||
.umb-tree .umb-tree-node-checked i:before {
|
||||
/*check box*/
|
||||
content: "\e165" !important;
|
||||
}
|
||||
|
||||
a.umb-options {
|
||||
visibility: hidden;
|
||||
cursor: pointer;
|
||||
@@ -224,6 +236,7 @@ li.root > div > a.umb-options {
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Tree item states
|
||||
// -------------------------
|
||||
div.not-published > i.icon,div.not-published > a{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//used for the media picker dialog
|
||||
angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController",
|
||||
function ($scope, entityResource, eventsService, $log, searchService, angularHelper, $timeout, localizationService) {
|
||||
function ($scope, entityResource, eventsService, $log, searchService, angularHelper, $timeout, localizationService, treeService) {
|
||||
|
||||
var tree = null;
|
||||
var dialogOptions = $scope.dialogOptions;
|
||||
@@ -75,20 +75,25 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController",
|
||||
child.children = [
|
||||
{
|
||||
level: child.level + 1,
|
||||
hasChildren: false,
|
||||
hasChildren: false,
|
||||
parent: function () {
|
||||
return child;
|
||||
},
|
||||
name: searchText,
|
||||
metaData: {
|
||||
listViewNode: child,
|
||||
},
|
||||
cssClass: "icon umb-tree-icon sprTree icon-search",
|
||||
cssClass: "icon-search",
|
||||
cssClasses: ["not-published"]
|
||||
}
|
||||
];
|
||||
//add base transition classes to this node
|
||||
child.cssClasses.push("tree-node-slide-up");
|
||||
|
||||
var listViewResults = _.filter($scope.searchInfo.selectedSearchResults, function(i) {
|
||||
return i.parentId == child.id;
|
||||
});
|
||||
_.each(listViewResults, function(item) {
|
||||
var parent = child;
|
||||
child.children.unshift({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
@@ -99,7 +104,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController",
|
||||
},
|
||||
hasChildren: false,
|
||||
parent: function () {
|
||||
return parent;
|
||||
return child;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -138,6 +143,10 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController",
|
||||
$scope.searchInfo.showSearch = true;
|
||||
$scope.searchInfo.searchFromId = args.node.metaData.listViewNode.id;
|
||||
$scope.searchInfo.searchFromName = args.node.metaData.listViewNode.name;
|
||||
|
||||
//add transition classes
|
||||
var listViewNode = args.node.parent();
|
||||
listViewNode.cssClasses.push('tree-node-slide-up-hide-active');
|
||||
}
|
||||
else if (args.node.metaData.isSearchResult) {
|
||||
//check if the item selected was a search result from a list view
|
||||
@@ -258,14 +267,20 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController",
|
||||
return i.id == result.id;
|
||||
});
|
||||
}
|
||||
|
||||
//ensure the tree node in the tree is checked/unchecked if it already exists there
|
||||
if (tree) {
|
||||
var found = treeService.getDescendantNode(tree.root, result.id);
|
||||
if (found) {
|
||||
found.selected = result.selected;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$scope.hideSearch = function () {
|
||||
|
||||
//TODO: Move this to the treeService, we don't need a reference to the 'tree' the way this is working
|
||||
// because if we have a single node, that is all we need since we can traverse to the tree root in the treeService.
|
||||
// this logic needs to be centralized so it can be used in other tree + search areas.
|
||||
|
||||
|
||||
//Traverse the entire displayed tree and update each node to sync with the selected search results
|
||||
if (tree) {
|
||||
|
||||
//we need to ensure that any currently displayed nodes that get selected
|
||||
@@ -290,14 +305,15 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController",
|
||||
return c.id == child.id;
|
||||
});
|
||||
}
|
||||
else {
|
||||
//it's not part of any search result, uncheck it
|
||||
child.selected = false;
|
||||
}
|
||||
|
||||
|
||||
//check if the current node is a list view and if so, check if there's any new results
|
||||
// that need to be added as child nodes to it based on search results selected
|
||||
if (child.metaData.isContainer) {
|
||||
|
||||
child.cssClasses = _.reject(child.cssClasses, function(c) {
|
||||
return c === 'tree-node-slide-up-hide-active';
|
||||
});
|
||||
|
||||
var listViewResults = _.filter($scope.searchInfo.selectedSearchResults, function (i) {
|
||||
return i.parentId == child.id;
|
||||
});
|
||||
|
||||
@@ -17,22 +17,21 @@
|
||||
<div class="tab-content umb-control-group">
|
||||
|
||||
<umb-tree-search-results
|
||||
ng-if="searchInfo.showSearch"
|
||||
ng-if="searchInfo.showSearch"
|
||||
results="searchInfo.results"
|
||||
select-result-callback="selectResult">
|
||||
</umb-tree-search-results>
|
||||
|
||||
<div ng-hide="searchInfo.showSearch">
|
||||
<umb-tree
|
||||
section="{{section}}"
|
||||
treealias="{{treeAlias}}"
|
||||
hideheader="{{hideHeader}}"
|
||||
hideoptions="true"
|
||||
isdialog="true"
|
||||
customtreeparams="{{customTreeParams}}"
|
||||
eventhandler="dialogTreeEventHandler"
|
||||
enablelistviewsearch="true"
|
||||
enablecheckboxes="{{multiPicker}}">
|
||||
<div ng-hide="searchInfo.showSearch" ng-animate="'tree-fade-out'">
|
||||
<umb-tree section="{{section}}"
|
||||
treealias="{{treeAlias}}"
|
||||
hideheader="{{hideHeader}}"
|
||||
hideoptions="true"
|
||||
isdialog="true"
|
||||
customtreeparams="{{customTreeParams}}"
|
||||
eventhandler="dialogTreeEventHandler"
|
||||
enablelistviewsearch="true"
|
||||
enablecheckboxes="{{multiPicker}}">
|
||||
</umb-tree>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user