diff --git a/frappe/desk/treeview.py b/frappe/desk/treeview.py
index fa2f3b65f5..6b0cef4ec3 100644
--- a/frappe/desk/treeview.py
+++ b/frappe/desk/treeview.py
@@ -2,7 +2,33 @@
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
-import frappe
+import frappe, json
+from frappe import _
+
+@frappe.whitelist()
+def get_all_nodes(tree_method, tree_args, parent):
+ '''Recursively gets all data from tree nodes'''
+
+ tree_method = frappe.get_attr(tree_method)
+
+ if not tree_method in frappe.whitelisted:
+ frappe.throw(_("Not Permitted"), frappe.PermissionError)
+
+ frappe.local.form_dict = frappe._dict(json.loads(tree_args))
+ frappe.local.form_dict.parent = parent
+ data = tree_method()
+ out = [dict(parent=parent, data=data)]
+
+ to_check = [d.value for d in data if d.expandable]
+ while to_check:
+ frappe.local.form_dict.parent = to_check.pop()
+ data = tree_method()
+ out.append(dict(parent=frappe.local.form_dict.parent, data=data))
+ for d in data:
+ if d.expandable:
+ to_check.append(d.value)
+
+ return out
@frappe.whitelist()
def get_children():
diff --git a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js
index 167cad6b18..b9f62f4bb5 100644
--- a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js
+++ b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js
@@ -129,7 +129,7 @@ frappe.search = {
if(route[0]==='Form') {
values.push([route[2], route]);
}
- else if(in_list(['List', 'Report', 'modules', 'query-report'], route[0])) {
+ else if(in_list(['List', 'Report', 'Tree', 'modules', 'query-report'], route[0])) {
if(route[1]) {
values.push([route[1], route]);
}
@@ -146,7 +146,7 @@ frappe.search = {
if(match[1][0]==='Form') {
out.label = __(match[1][1]) + " " + match[1][2].bold();
out.value = __(match[1][1]) + " " + match[1][2];
- } else if(in_list(['List', 'Report', 'modules', 'query-report'], match[1][0])) {
+ } else if(in_list(['List', 'Report', 'Tree', 'modules', 'query-report'], match[1][0])) {
var type = match[1][0], label = type;
if(type==='modules') label = 'Module';
else if(type==='query-report') label = 'Report';
diff --git a/frappe/public/js/frappe/ui/tree.js b/frappe/public/js/frappe/ui/tree.js
index ff05f9ccff..404f78b681 100644
--- a/frappe/public/js/frappe/ui/tree.js
+++ b/frappe/public/js/frappe/ui/tree.js
@@ -163,7 +163,7 @@ frappe.ui.TreeNode = Class.extend({
var $li = $('
');
if(this.tree.drop) $li.draggable({revert:true});
return new frappe.ui.TreeNode({
- tree:this.tree,
+ tree: this.tree,
parent: $li.appendTo(this.$ul),
parent_label: this.label,
label: data.value,
@@ -200,6 +200,23 @@ frappe.ui.TreeNode = Class.extend({
reload_parent: function() {
this.parent_node.load();
},
+ load_all: function(callback) {
+ var me = this;
+ return frappe.call({
+ method: 'frappe.desk.treeview.get_all_nodes',
+ args: {
+ tree_args: this.tree.args,
+ tree_method: this.tree.method,
+ parent: this.data.value
+ },
+ callback: function(r) {
+ $.each(r.message, function(i, d) {
+ me.render_expand_node(me.tree.nodes[d.parent], d.data);
+ });
+ if(callback) { callback(); }
+ }
+ });
+ },
load: function(callback) {
var node = this;
args = $.extend(this.tree.args || {}, {
@@ -210,20 +227,23 @@ frappe.ui.TreeNode = Class.extend({
method: this.tree.method,
args: args,
callback: function(r) {
- node.$ul.empty();
- if (r.message) {
- $.each(r.message, function(i, v) {
- var child_node = node.addnode(v);
- child_node.$a
- .data('node-data', v)
- .data('node', child_node);
- });
- }
-
- node.expanded = false;
- node.toggle_node(callback);
- node.loaded = true;
+ node.render_expand_node(node, r.message, callback);
}
})
- }
+ },
+ render_expand_node: function(node, data, callback) {
+ node.$ul.empty();
+ if (data) {
+ $.each(data, function(i, v) {
+ var child_node = node.addnode(v);
+ child_node.$a
+ .data('node-data', v)
+ .data('node', child_node);
+ });
+ }
+
+ node.expanded = false;
+ node.toggle_node(callback);
+ node.loaded = true;
+ },
})
diff --git a/frappe/public/js/frappe/views/treeview.js b/frappe/public/js/frappe/views/treeview.js
index f699e6cf60..b06eca5d3a 100644
--- a/frappe/public/js/frappe/views/treeview.js
+++ b/frappe/public/js/frappe/views/treeview.js
@@ -1,7 +1,8 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
-frappe.provide("frappe.treeview_settings")
+frappe.provide("frappe.treeview_settings");
+cur_tree = null;
frappe.views.TreeFactory = frappe.views.Factory.extend({
make: function(route) {
@@ -64,6 +65,10 @@ frappe.views.TreeView = Class.extend({
this.page.main.css({
"min-height": "300px",
"padding-bottom": "25px"
+ });
+
+ this.page.add_inner_button(__('Expand All'), function() {
+ me.tree.rootnode.load_all();
})
},
make_filters: function(){
@@ -73,7 +78,7 @@ frappe.views.TreeView = Class.extend({
if(frappe.route_options && frappe.route_options[filter.fieldname]) {
filter.default = frappe.route_options[filter.fieldname]
}
-
+
me.page.add_field(filter).$input
.change(function() {
me.args[$(this).attr("data-fieldname")] = $(this).val();
@@ -111,10 +116,11 @@ frappe.views.TreeView = Class.extend({
get_label: me.opts.get_label,
onrender: me.opts.onrender
});
+ cur_tree = this.tree;
},
get_toolbar: function(){
var me = this;
-
+
var toolbar = [
{toggle_btn: true},
{
@@ -155,7 +161,7 @@ frappe.views.TreeView = Class.extend({
btnClass: "hidden-xs"
}
]
-
+
if(this.opts.toolbar && this.opts.extend_toolbar) {
return toolbar.concat(this.opts.toolbar)
} else if (this.opts.toolbar && !this.opts.extend_toolbar) {