bricks/bricks/dynamicaccordion.js
2024-03-14 21:49:48 +08:00

353 lines
8.6 KiB
JavaScript

var bricks = window.bricks || {};
bricks.PageContent = class extends bricks.Layout {
constructor(opts){
super(opts);
}
}
bricks.AccordionItem = class extends bricks.Layout {
constructor(opts){
super(opts);
this.set_css('accordion-item');
}
}
bricks.AccordionInfo = class extends bricks.Layout {
constructor(opts){
super(opts);
this.set_css('accordion-item-info');
}
}
bricks.DynamicAccordion = class extends bricks.VScrollPanel {
/*
{
"data_url",
"data_method",
"cache_limit",
"page_rows",
"record_view"
"content_rely_on"
"content_rely_value"
"editable"
"fields":
"record_toolbar",
"record_toolbar_collapsable"
"header"
"content_view"
}
*/
constructor(opts){
super(opts);
this.element = this.dom_element;
this.loader = new bricks.PageDataLoader({
url:this.opts.data_url,
params:this.opts.data_params,
pagerows:this.opts.page_rows,
method:this.opts.data_method,
cache_pages:this.opts.cache_limit
});
this.old_params = null;
this.active_item = null;
this.active_content = null;
this.loading = false;
schedule_once(this.build_all.bind(this), 0.1);
}
async build_all(){
if (this.title){
this.build_title();
}
if (this.description){
this.build_description();
}
if (this.toolbar){
await this.build_toolbar();
}
if (this.editable && this.fields){
await this.build_new_form();
}
if (! this.noheader){
await this.build_header();
}
var filler = new bricks.Filler();
this.container = new bricks.VScrollPanel({ });
filler.add_widget(this.container);
this.add_widget(filler);
this.container.bind('min_threshold', this.load_previous_page.bind(this));
this.container.bind('max_threshold', this.load_next_page.bind(this));
await this.render();
}
async build_header(){
await this.build_info(this);
}
async build_info(item, record){
if (! this.fields && !record){
return;
}
var w;
var tb = null;
var info = new bricks.AccordionInfo({});
info.data = record;
item.add_widget(info);
if (this.editable){
tb = this.build_record_toolbar(info, record);
}
if (! record){
record = {};
for (var i=0;i<this.fields.length;i++){
var f = this.fields[i];
record[f.name] = f.label || f.name;
}
}
w = await bricks.widgetBuild(this.record_view, info, record);
if (w){
if (tb){
w.add_widget(tb, 0);
}
info.add_widget(w);
} else {
bricks.debug('bricks.widgetBuild(), tmpl=', this.record_view, 'record=', record);
}
return info;
}
update_record(info, record){
console.log('update_record():info=', info)
var w = info.parent;
var hided;
var content = w.children[1];
var hided = content.is_hide();
var fields = [];
for (var i=0; i< this.fields.length; i++){
var f = bricks.extend({}, this.fields[i]);
f.value = record[f.name];
fields.push(f);
}
var f = new bricks.Form({
"cheight":this.editable.form_cheight||7,
"submit_url":this.editable.update_data_url+'?id=' + record.id,
"fields":fields
});
content.add_widget(f, 0);
if (hided){
content.show();
}
f.bind('submited', this.update_record_finish.bind(this, info, content, hided, f));
}
async update_record_finish(info, content, hided, form){
var d = form.getValue();
content.remove_widget(form);
if (hided){
content.hide();
}
var record = bricks.extend(info.data, d);
var w = info.children[0];
info.clear_widgets();
var rtb = w.children[0];
var w = await bricks.widgetBuild(this.record_view, info, record);
w.add_widget(rtb, 0);
info.add_widget(w);
}
delete_record(info, record){
}
async build_new_form(){
var desc = {
"widgettype":"VBox",
"options":{
"height":"auto",
},
"subwidgets":[
{
"id":"new",
"widgettype":"IconBar",
"options":{
"tools":[
{
"name":"add",
"tip":"add a new record",
"icon":this.editable.add_icon || bricks_resource('imgs/add.png')
}
]
}
},
{
"widgettype":"Form",
"options":{
"cheight":this.editable.form_cheight||7,
"submit_url":this.editable.new_data_url,
"fields":this.fields
}
}
]
};
var w = await bricks.widgetBuild(desc, this);
w.children[1].hide();
w.children[0].bind('add',function(){ w.children[1].toggle_hide()})
this.new_form = w.children[1];
this.new_form.bind('submited', this.render.bind(this));
this.add_widget(w);
}
async render(params) {
params = params || {};
if (params == this.old_params){
return;
}
this.old_params = params;
bricks.debug('params=', params, 'render() called');
var d = await this.loader.loadData(params);
if (d){
this.container.clear_widgets();
await this.dataHandle(d);
} else {
bricks.debug(params, 'load data return null');
}
}
async dataHandle(d){
var data = d.rows;
var page = d.add_page;
await this.renderAccordionItems(data, page);
if (d.delete_page){
this.delete_page(d.delete_page);
}
}
build_record_toolbar(info, record){
var c = new bricks.Layout({cwidth:2.5, height:'auto'})
if (! record){
c.set_style('height', '20px');
return c;
}
var desc = {
cwidth:2.5,
tools:[
{
name:"update",
tip:"update record in this line",
icon:this.editable.update_icon || bricks_resource('imgs/update.png')
},
{
name:'delete',
tip:"delete record in this line",
icon:this.editable.delete_icon || bricks_resource('imgs/delete.png')
}
]
}
var w = new bricks.IconBar(desc);
w.bind('update', this.update_record.bind(this, info, record));
w.bind('delete', this.delete_record.bind(this, info, record));
c.add_widget(w);
return c;
}
async renderAccordionItems(data, page) {
var pos;
for (var i=0;i<data.length;i++){
if (this.loader.is_max_page(page)){
pos = -1;
} else {
pos = i;
}
var record = data[i];
var item = new bricks.AccordionItem({});
var info = await this.build_info(item, record);
this.content_rely_value = this.content_rely_value || true;
var build_content = true;
if (this.content_rely_on){
var v = this.content_rely_value || true;
if(record[this.content_rely_on] != v){
build_content = false;
}
}
content = null;
var content = new bricks.VBox({
height:'auto',
display:'none'
});
content.set_css('accordion-item-content');
content.hide();
if ( build_content ){
info.bind('click', this.toggle_content.bind(this, info, content, record));
}
item.add_widget(content);
item.set_attribute('data-page', page);
this.container.add_widget(item, pos);
};
}
delete_page(page){
var items = this.dom_element.querySelectorAll('[data-page="' + page + '"]');
for (var i=0;i<items.length;i++) {
var w = items[i].bricks_widget;
this.container.remove_widget(w);
}
}
async toggle_content(info, content, record, event){
var h = this.container.dom_element.offsetHeight - 3 * info.dom_element.offsetHeight;
content.set_style('height', h + 'px');
if (this.active_content){
if (this.active_content != content){
this.active_content.clear_widgets();
this.active_content.hide();
this.active_content = null;
}
}
content.toggle_hide();
if (content.dom_element.style.display == 'none'){
bricks.debug('content just collapsed');
content.clear_widgets();
this.active_content = null;
return;
}
var jc = new bricks.HttpJson();
var w;
w = await bricks.widgetBuild(this.content_view, content, record);
if (w){
content.add_widget(w);
this.active_content = content;
} else {
this.active_content = null;
content.hide();
}
}
async load_previous_page(){
if (this.loading){
bricks.debug('this.loading is set, do not thing');
return;
}
this.loading = true;
try {
var d = await this.loader.loadPreviousPage();
if (d){
this.dataHandle(d);
var total = this.container.dom_element.scrollHeight - this.container.dom_element.clientHeight;
this.container.dom_element.scrollTop = d.pos_rate * total;
} else {
bricks.debug(this.loader, 'load previous page error');
}
} catch (e) {
bricks.debug('e=', e);
}
this.loading = false;
}
async load_next_page(){
if (this.loading){
bricks.debug('this.loading is set, do not thing');
return;
}
this.loading = true;
try {
var d = await this.loader.loadNextPage();
if (d){
this.dataHandle(d);
var total = this.container.dom_element.scrollHeight - this.container.dom_element.clientHeight;
this.container.dom_element.scrollTop = d.pos_rate * total;
} else {
bricks.debug(this.loader, 'load next page error');
}
} catch (e){
bricks.debug('error happened', e);
}
this.loading = false;
bricks.debug('load_next_page() finished');
}
}
bricks.Factory.register('DynamicAccordion', bricks.DynamicAccordion);