bricks/bricks/tree.js

450 lines
11 KiB
JavaScript
Raw Normal View History

2024-02-01 17:54:04 +08:00
var bricks = window.bricks || {};
2024-02-22 00:48:58 +08:00
bricks.TreeNode = class extends bricks.VBox {
2024-05-21 14:47:08 +08:00
constructor(tree, pnode, data){
2023-09-14 10:28:07 +08:00
var opts = {
width:'100%',
height:'auto',
}
super(opts);
this.tree = tree;
2024-05-21 14:47:08 +08:00
this.parent_node = pnode;
2023-09-14 10:28:07 +08:00
this.children_loaded = false;
2024-05-21 14:47:08 +08:00
this.user_data = data;
this.is_leaf = this.user_data.is_leaf;
this.params = {id:this.user_data[this.tree.opts.idField]};
2023-09-14 10:28:07 +08:00
if (this.tree.multitype_tree){
2024-05-21 14:47:08 +08:00
this.params['type'] = this.user_data[this.tree.opts.typeField];
2023-09-14 10:28:07 +08:00
}
2024-02-01 17:54:04 +08:00
var n = new bricks.HBox({
2024-02-25 12:31:02 +08:00
height:this.tree.row_height,
2023-09-14 10:28:07 +08:00
width:'100%'
})
2024-02-01 16:40:31 +08:00
n.dom_element.style.margin = bricks.app.charsize * 0.2;
2023-09-14 10:28:07 +08:00
this.add_widget(n);
n.bind('click', this.tree.node_click_handle.bind(this.tree, this));
this.node_widget = n;
2024-05-22 12:03:44 +08:00
schedule_once(this.create_node_content.bind(this,n), 0.01);
2024-05-21 14:47:08 +08:00
if (! this.user_data.is_leaf) {
2024-02-25 12:31:02 +08:00
this.container = new bricks.VBox({height:'auto'});
2023-09-14 10:28:07 +08:00
this.add_widget(this.container);
2024-02-01 16:40:31 +08:00
this.container.dom_element.style.marginLeft = bricks.app.charsize + 'px';
2024-05-21 14:47:08 +08:00
if (this.user_data.children){
this.tree.create_node_children(this, this.user_data.children);
2023-09-14 10:28:07 +08:00
}
this.container.hide();
}
}
2024-05-20 18:16:38 +08:00
getValue(){
2024-05-22 12:03:44 +08:00
var v = this.user_data;
if (this.container){
var children = [];
for (var i=0; i<this.container.children.length;i++){
var sv = this.container.children[i].getValue();
children.push(sv);
}
v.children = children;
}
return v;
2024-05-20 18:16:38 +08:00
}
get_id(){
2024-05-21 14:47:08 +08:00
return this.user_data[this.tree.idField];
2024-05-20 18:16:38 +08:00
}
2023-09-14 10:28:07 +08:00
selected(flg){
if (flg){
this.str_w.set_css('selected');
} else {
this.str_w.set_css('selected',true);
}
}
async toggleExpandCollapse(event){
if (event.params == 'open') {
await this.expand();
} else {
this.collapse()
}
}
async expand(){
if (this.is_leaf){
return;
}
if (this.tree.opts.dataurl && !this.is_leaf && !this.children_loaded){
await this.tree.get_children_data(this)
this.children_loaded = true;
}
this.container.show();
}
collapse(){
if (this.is_leaf){
return;
}
this.container.hide();
}
2024-05-22 12:03:44 +08:00
async create_node_content(widget){
2024-02-01 16:40:31 +08:00
var img_size = bricks.app.charsize;
2023-09-14 10:28:07 +08:00
if (this.is_leaf){
2024-02-01 17:54:04 +08:00
widget.add_widget(new bricks.BlankIcon({}));
2023-09-14 10:28:07 +08:00
} else {
var srcs = this.tree.opts.node_state_imgs || {};
var sources = {};
sources['open'] = objget(srcs, 'open', bricks_resource('imgs/down_arrow.png'));
sources['close'] = objget(srcs, 'close', bricks_resource('imgs/right_arrow.png'));
2024-02-01 17:54:04 +08:00
this.trigle = new bricks.MultipleStateIcon({
2023-09-14 10:28:07 +08:00
state:'close',
urls:sources,
height:img_size,
width:img_size
});
this.trigle.bind('state_changed', this.toggleExpandCollapse.bind(this));
widget.add_widget(this.trigle);
}
2024-05-21 18:56:27 +08:00
if (this.tree.checkField){
var v = this.user_data[this.tree.checkField];
this.check_w = new bricks.UiCheck({name:'check', value:v});
2024-05-20 18:16:38 +08:00
widget.add_widget(this.check_w);
this.check_w.bind('changed', this.tree.node_checked.bind(this.tree, this))
}
2024-05-21 14:47:08 +08:00
var dtype = this.user_data[this.tree.opts.typeField];
2023-09-14 10:28:07 +08:00
var icon = objget(TypeIcons, dtype);
if (!icon && this.tree.opts.default_type){
icon = objget(TypeIcons, his.tree.opts.default_type);
}
if (!icon){
icon = bricks_resource('imgs/folder.png');
}
2024-02-01 17:54:04 +08:00
var img = new bricks.Icon({
2023-09-14 10:28:07 +08:00
url:icon
});
widget.add_widget(img);
2024-05-22 12:03:44 +08:00
if (this.tree.node_view){
this.view_w = await bricks.widgetBuild(this.tree.node_view, widget, this.user_data);
if (this.view_w){
widget.add_widget(this.view_w);
}
} else {
var txt = this.user_data[this.tree.opts.textField];
this.str_w = new bricks.Text({text:txt});
widget.add_widget(this.str_w);
}
2023-09-14 10:28:07 +08:00
}
2024-05-22 12:03:44 +08:00
async update_content(){
if (this.tree.node_view){
this.node_widget.remove_Widget(this.view_w);
this.view_w = await bricks.widgetBuild(this.tree.node_view, widget, this.user_data);
if (this.view_w){
widget.add_widget(this.view_w);
}
} else {
this.str_w.set_text(this.user_data[this.tree.opts.textField]);
}
2023-09-14 10:28:07 +08:00
}
}
2024-02-22 00:48:58 +08:00
bricks.Tree = class extends bricks.VScrollPanel {
2023-09-14 10:28:07 +08:00
/*
{
row_height:
multitype_tree:false,
idField:
textField:
type_icons:
typeField:
default_type:
data:
dataurl:
node_state_imgs:{
open:url,
close:url
},
admin:{
{
addurl:
deleteurl:
updateurl:
othertools:[
]
}
}
}
*/
constructor(options){
super(options);
this.row_height = this.opts.row_height || '35px';
this.multitype_tree = this.opts.multitype_tree||false;
this.selected_node = null;
this.create_toolbar();
2024-05-20 18:16:38 +08:00
this.checked_nodes = [];
2024-02-25 12:31:02 +08:00
this.container = new bricks.VBox({
"width":"100%",
"height":"auto",
"overflow":"auto"
});
2023-09-14 10:28:07 +08:00
this.add_widget(this.container);
this.data_id = null;
if (this.opts.dataurl){
2024-05-20 18:16:38 +08:00
schedule_once(this.get_children_data.bind(this, this), 0.1);
} else {
2024-05-21 14:47:08 +08:00
this.user_data = {
id:null,
children:this.opts.data
}
2024-05-20 18:16:38 +08:00
this.create_node_children(this, this.opts.data);
2023-09-14 10:28:07 +08:00
}
2024-05-21 14:47:08 +08:00
this.bind('node_selected',this.node_info_log.bind(this));
2023-09-14 10:28:07 +08:00
}
2024-05-20 18:28:57 +08:00
getValue(){
2024-05-22 12:03:44 +08:00
var v = this.user_data;
if (this.container){
var children = [];
for (var i=0; i<this.container.children.length;i++){
var sv = this.container.children[i].getValue();
children.push(sv);
}
v.children = children;
}
return v;
2024-05-20 18:28:57 +08:00
}
get_id(){
2024-05-21 14:47:08 +08:00
return this.user_data[this.idField];
2024-05-20 18:28:57 +08:00
}
2023-09-14 10:28:07 +08:00
create_toolbar(){
2024-05-14 17:47:24 +08:00
var toolbar = bricks.extend({}, this.toolbar);
var tools = [];
2024-05-20 18:16:38 +08:00
if (toolbar.tools){
toolbar.tools.forEach(f => tools.push(f));
}
2024-05-14 17:47:24 +08:00
if (this.editable){
tools.push({icon:bricks_resource('imgs/add.png'), name:'add'});
tools.push({icon:bricks_resource('imgs/update.png'), name:'update'});
tools.push({icon:bricks_resource('imgs/delete.png'), name:'delete'});
}
2024-05-20 18:16:38 +08:00
if (tools.length == 0){
return;
}
2024-05-14 17:47:24 +08:00
toolbar.tools = tools;
this.toolbar_w = new bricks.IconBar(toolbar);
this.add_widget(this.toolbar_w);
this.toolbar_w.bind('add', this.add_new_node.bind(this));
2024-05-20 18:16:38 +08:00
this.toolbar_w.bind('delete', this.delete_node.bind(this));
2024-05-14 17:47:24 +08:00
this.toolbar_w.bind('update', this.update_node.bind(this));
2023-09-14 10:28:07 +08:00
}
2024-05-20 18:16:38 +08:00
async add_new_node(){
var w = new bricks.ModalForm({
target:this,
"width":"80%",
"height":"80%",
title:'add new node',
fields:this.editable.fields
});
w.bind('submit', this.new_node_inputed.bind(this))
}
async new_node_inputed(event){
var d = event.params;
var node = this;
if (this.selected_node){
node = this.selected_node;
2024-05-21 14:47:08 +08:00
d[this.parentField] = node.get_id();
2024-05-20 18:16:38 +08:00
}
2024-05-22 12:03:44 +08:00
if (this.editable.add_url){
var jc = new bricks.HttpJson()
var desc = await jc.post(this.editable.add_url, {params:d});
if (desc.widgettype == 'Message'){
var data = desc.options.user_data;
this.append_new_subnode(node, data);
}
var w = await bricks.widgetBuild(desc, this);
w.open();
} else {
d[this.idField] = bricks.uuid();
this.append_new_subnode(node, d);
2024-05-20 18:16:38 +08:00
}
}
async create_tree_nodes(node, records){
for (var i=0;i<records.length;i++){
this.build_subnode(node, records[i]);
}
}
2024-05-21 14:47:08 +08:00
append_new_subnode(node, data){
data.is_left = true;
if (!node.user_data.children){
node.user_data.children = [];
}
node.is_leaf = false;
node.children_loaded = true;
node.user_data.children.push(data)
this.build_subnode(node, data);
}
2024-05-20 18:16:38 +08:00
build_subnode(node, data){
var n = new bricks.TreeNode(this, node, data);
node.container.add_widget(n);
}
async delete_node(){
2024-05-21 14:47:08 +08:00
if (! this.selected_node){
w = new bricks.Error({title:'Delete', message:'No selected node found'});
w.open();
return;
}
var w = new bricks.Conform({
title:'Delete node',
message:'Please conform delete selected node'
});
w.bind('conformed', this.delete_node_conformed.bind(this))
}
async delete_node_conformed(event){
var d = {};
d[this.idField] = this.selected_node.get_id();
2024-05-22 12:03:44 +08:00
if (this.editable.delete_url){
var jc = new bricks.HttpJson()
var desc = await jc.post(this.editable.delete_url, {params:d});
if (desc.widgettype == 'Message'){
var pnode = this.selected_node.parent_node;
console.log('parent node=', pnode);
if (pnode && pnode.container){
pnode.container.remove_widget(this.selected_node);
}
this.selected_node = null;
}
var w = await bricks.widgetBuild(desc, this);
w.open();
} else {
2024-05-21 14:47:08 +08:00
var pnode = this.selected_node.parent_node;
if (pnode && pnode.container){
pnode.container.remove_widget(this.selected_node);
}
this.selected_node = null;
}
}
delete_subnode(node, subnode){
var subid = subnode.user_data[this.idField];
var children = [];
for (var i=0;i< node.user_data.children.length;i++){
var c = node.user_data.children[i];
if (c[this.idField] != subid){
children.push(c);
}
}
node.user_data.children = children;
node.container.remove_widget(subnode);
2024-05-20 18:16:38 +08:00
}
async update_node(){
2024-05-21 14:47:08 +08:00
if (! this.selected_node){
w = new bricks.Error({title:'Update', message:'No selected node found'});
w.open();
return;
}
var fields = [];
for (var i=0;i<this.editable.fields.length;i++){
var f = bricks.extend({}, this.editable.fields[i]);
f.value = this.selected_node.user_data[f.name];
fields.push(f);
}
var w = new bricks.ModalForm({
target:this,
"width":"80%",
"height":"80%",
title:'add new node',
fields:fields
});
w.bind('submit', this.update_node_inputed.bind(this))
}
async update_node_inputed(event){
var d = event.params;
var node = this.selected_node;
d[this.idField] = node.get_id();
2024-05-22 12:03:44 +08:00
if(this.editable.update_url){
var jc = new bricks.HttpJson()
var desc = await jc.post(this.editable.update_url, {params:d});
if (desc.widgettype == 'Message'){
await this.update_node_data(node, d);
}
var w = await bricks.widgetBuild(desc, this);
w.open();
} else {
await this.update_node_data(node, d);
2024-05-21 14:47:08 +08:00
}
}
2024-05-22 12:03:44 +08:00
async update_node_data(node, data){
2024-05-21 14:47:08 +08:00
for (var name in Object.keys(data)){
node.user_data[name] = data[name];
}
2024-05-22 12:03:44 +08:00
await node.update_content();
2024-05-20 18:16:38 +08:00
}
2023-09-14 10:28:07 +08:00
async get_children_data(node){
2024-02-01 17:54:04 +08:00
var jcall = bricks.jcall;
2023-09-14 10:28:07 +08:00
var d = await jcall(this.opts.dataurl,{
method : this.opts.method || 'GET',
params : node.params
})
if (d.length == 0){
node.is_leaf = true;
} else {
2024-05-21 14:47:08 +08:00
this.user_data = {
children:d
}
2023-09-14 10:28:07 +08:00
this.create_tree_nodes(node, d);
}
}
create_node_children(node, data){
2024-05-20 18:16:38 +08:00
if(!data) return;
2023-09-14 10:28:07 +08:00
for (var i=0; i<data.length; i++){
2024-02-01 17:54:04 +08:00
var n = new bricks.TreeNode(this, node, data[i]);
2023-09-14 10:28:07 +08:00
node.container.add_widget(n);
}
}
node_click_handle(node, event){
2024-05-21 14:47:08 +08:00
if (this.selected_node){
this.node_selected(this.selected_node, false);
}
2024-05-14 17:47:24 +08:00
if (this.selected_node == node){
2024-05-21 14:47:08 +08:00
this.selected_node = null;
2024-05-14 17:47:24 +08:00
} else {
this.selected_node = node;
2024-05-20 18:16:38 +08:00
this.node_selected(node, true);
}
}
node_selected(node, flag){
2024-05-21 14:47:08 +08:00
console.log('node_selected():node=', node, flag);
2024-05-20 18:16:38 +08:00
node.selected(flag);
var d = {
node:node,
data:node.getValue(),
id:node.get_id(),
selected:flag
}
2024-05-21 14:47:08 +08:00
this.dispatch('node_selected', d);
2024-05-20 18:16:38 +08:00
}
async node_checked(node, event){
var cb = event.target.bricks_widget;
var stat = cb.getValue().check;
2024-05-21 18:56:27 +08:00
node.user_data[this.checkField] = stat;
2024-05-20 18:16:38 +08:00
var d = {
node:node,
data:node.getValue(),
id: node.get_id(),
check_stat:stat
2023-09-14 10:28:07 +08:00
}
2024-05-21 18:56:27 +08:00
console.log('value=', cb.getValue(), 'node=', node);
2024-05-20 18:16:38 +08:00
this.dispatch('check_changed', d);
2023-09-14 10:28:07 +08:00
}
2024-05-21 14:47:08 +08:00
node_info_log(event){
if (event.params.selected == false){
2023-09-14 10:28:07 +08:00
return;
}
2024-05-21 14:47:08 +08:00
var node = event.params.node;
console.log('======node info========');
console.log('user_data=', node.user_data);
console.log('parent=', node.parent_node);
console.log('container=', node.container);
console.log('======node info end========');
2023-09-14 10:28:07 +08:00
}
}
2024-05-21 14:47:08 +08:00
2024-02-01 16:40:31 +08:00
bricks.Factory.register('Tree', bricks.Tree);
bricks.Factory.register('EditableTree', bricks.EditableTree);