var bricks = window.bricks || {}; bricks.need_formdata_fields = ['file', 'video', 'audio']; bricks.show_resp_message_or_error = async function(resp){ var desc = await resp.json(); await bricks.widgetBuild(desc, bricks.Body); } bricks.FieldGroup = class { constructor(opts){ this.opts = opts } build_fields(form, parent, fields){ var dc = new bricks.DynamicColumn({mobile_cols:2}); for (var i=0;i0){ parent.add_widget(dc); dc = new bricks.DynamicColumn({mobile_cols:2}); } this.build_fields(form, dc, fields[i].fields); parent.add_widget(dc); dc = new bricks.DynamicColumn({mobile_cols:2}); dc.set_id(fields[i].name+'_box'); if (fields[i].nonuse){ dc.disabled(true); dc.hide(); } } else { var box; if (! form.opts.input_layout || form.opts.input_layout == 'VBox'){ box = new bricks.VBox({height:'auto',overflow:'none'}); } else { box = new bricks.HBox({height:'auto',overflow:'none'}); } box.set_css('inputbox'); if (fields[i].uitype !== 'hide'){ dc.add_widget(box); } if(bricks.need_formdata_fields.includes(fields[i].uitype)){ form.need_formdata = true; } var txt = new bricks.Text({ otext:fields[i].label||fields[i].name, dynsize:true, height:'auto', i18n:true}); box.add_widget(txt); box.set_id(fields[i].name + '_box') if (fields[i].nonuse){ box.disabled(true); box.hide(); } var w = Input.factory(fields[i]); if (w){ box.add_widget(w); form.name_inputs[fields[i].name] = w; w.set_id(fields[i].name); } else { bricks.debug(fields[i], 'createInput failed'); } } } if (dc.children.length > 0){ parent.add_widget(dc); } } } bricks.FormBody = class extends bricks.VScrollPanel { /* { title: description: fields: [ { "name":, "label":, "removable": "icon": "content": }, ... ] exclusionfields:[ [a,b,c], # a,b,c互斥,a enabled,b,c必须disabled [x,y] # x,y互斥 ] } */ constructor(form, opts){ opts.width = '100%'; opts.height = '100%'; super(opts); this.form = form; this.name_inputs = {}; this.fg = new bricks.FieldGroup({}); this.fg.build_fields(form, this, form.nontextfields); this.build_text_fields(); } build_text_fields(){ this.form.textfields.forEach((f) => { var labelw = new bricks.Text({ cheight: 2, otext: f.label || f.name, i18n: true }); var txtw = new bricks.UiText({ name:f.name, css: "filler", value:f.value }); var cell = new bricks.VBox({ css: "inputbox", width: "100%", height: "45%" }); cell.add_widget(labelw); cell.add_widget(txtw); this.add_widget(cell); this.form.name_inputs[f.name] = txtw; cell.set_id(f.name); }); } create(){ this.dom_element = this._create('form'); } } /* submit_changed: false fields submit_url */ bricks.FormBase = class extends bricks.Layout { constructor(opts){ super(opts); this.name_inputs = {}; } build_toolbar(widget){ var box = new bricks.HBox({height:'auto', width:'100%'}); widget.add_widget(box); var tools = [ { icon:bricks_resource('imgs/submit.svg'), name:'submit', css:'submit_btn', label:'Submit' }, { icon:bricks_resource('imgs/reset.svg'), name:'reset', css:'reset_btn', label:'Reset' }, { icon:bricks_resource('imgs/cancel.svg'), name:'cancel', css:'clear_btn', label:'Cancel' } ] var tb_desc={}; var names = [ 'submit', 'reset', 'cancel' ]; if (this.toolbar){ tb_desc = bricks.extend(tb_desc, this.toolbar); tb_desc.tools = tools; tools.forEach(t => { if (! names.includes(t.name)) { tb_desc.tools.push(t); } }); this.toolbar.tools.forEach(t => { if (! names.includes(t.name)) { tb_desc.tools.push(t); } }); } else { tb_desc = { width:"auto", tools:tools }; } var tbw = new bricks.IconTextBar(tb_desc); tbw.bind('command', this.command_handle.bind(this)); box.add_widget(new bricks.Filler()); box.add_widget(tbw); box.add_widget(new bricks.Filler()); } command_handle(event){ var params = event.params; bricks.debug('Form(): click_handle() params=', params); if (!params){ error('click_handle() get a null params'); return } if (params.name == 'submit'){ this.validation(); } else if (params.name == 'cancel'){ this.cancel(); } else if (params.name == 'reset'){ this.reset_data(); } else { if (params.action){ f = bricks.buildEventHandler(this, params); if (f) f(event); } else { this.dispatch(params.name); } } } cancel(){ this.dispatch('cancel'); } reset_data(){ for (var name in this.name_inputs){ if (! this.name_inputs.hasOwnProperty(name)){ continue; } var w = this.name_inputs[name]; w.reset(); } } _getValue(){ var data = {}; for (var name in this.name_inputs){ if (! this.name_inputs.hasOwnProperty(name)){ continue; } var w = this.name_inputs[name]; var d = w.getValue(); if (w.required && ( d[name] == '' || d[name] === null)){ bricks.debug('data=', data, 'd=', d); new bricks.Error({title:'Requirement', message:'required field must input"' + w.label + '"'}) w.focus(); return; } bricks.extend(data, d); } return data; } getValue(){ if (this.data) { var ret = this.data; this.data = null; return ret; } return this.get_formdata(); } toggle_disable(field_name, flg){ var w = bricks.getWidgetById(field_name + '_box', this); if (! w) return; w.disabled(flg); if (flg) w.hide(); else w.show(); if (flg) return; this.exclusionfields.forEach(arr =>{ if (arr.include(field_name)){ arr.forEach(x => { if (x!=field_name){ var w1 = bricks.getWidgetById(x + '_box', this); if (w1) { w1.disabled(true); w1.hide(); } } }); } }); } enable_field(field_name){ this.toggle_disable(field_name, false); } disable_field(field_name){ this.toggle_disable(field_name, true); } get_formdata(){ var data = new FormData(); var changed = false; for (var name in this.name_inputs){ if (! this.name_inputs.hasOwnProperty(name)){ continue; } var w = this.name_inputs[name]; if (w.parent.is_disabled()) continue; var d = w.getValue(); if (w.required && ( d[name] == '' || d[name] === null)){ new bricks.Error({title:'Requirement', message:'required field must input"' + w.label + '"'}) w.focus(); return; } if (d[name] === null){ continue; } if (this.submit_changed){ if (name != 'id' && this.origin_data[name] == d[name]){ continue; } } w.set_formdata(data); changed = true; } this.data = data; if (changed){ return data; } return null } async validation(){ var running = new bricks.Running({target:this}); try { var data; data = this.get_formdata(); if (! data) { running.dismiss(); return; } // data = bricks.delete_null_values(data); this.dispatch('submit', data); if (this.submit_url){ var rc = new bricks.HttpResponse(); var resp = await rc.httpcall(this.submit_url, { method:this.method || 'POST', params:data }); this.dispatch('submited', resp); } } catch (e){ console.log('form submit error', e); } running.dismiss(); } save_origin_data(){ this.origin_data = {}; for (var name in this.name_inputs){ var w = this.name_inputs[name]; var d = w.getValue(); this.origin_data[name] = d[name]; } } } bricks.InlineForm = class extends bricks.FormBase { constructor(opts){ opts.height = "100%"; opts.width = "100%"; opts.overflow = "auto"; super(opts); this.fg = new bricks.FieldGroup({}); this.fg.build_fields(this, this, this.opts.fields) this.build_toolbar(this.children[0]); this.save_origin_data(); } } bricks.Form = class extends bricks.FormBase { /* { title: description: notoolbar:False, input_layout:"VBox" or "HBox", default is "VBox", cols: dataurl: toolbar: submit_url: method: exclussionfields:[ [a,b,c], [x,y] ] fields } field { name: label: uitype: nonuse: # 不使用 ... } */ constructor(opts){ opts.height = "100%"; opts.width = "100%"; opts.overflow = "auto"; super(opts); this.need_formdata = false; if (this.opts.title){ var t = new bricks.Title3({ otext:this.opts.title, height:'auto', i18n:true}); this.add_widget(t, 0); } if (this.opts.description){ var d = new bricks.Text({ otext:this.opts.description, height:'auto', i18n:true}); this.add_widget(d); } this.set_css('vcontainer'); var filler = new bricks.Filler({}); this.add_widget(filler); this.nontextfields = []; this.textfields = []; this.fields.forEach((f) => { if (f.uitype == 'text'){ this.textfields.push(f); } else { this.nontextfields.push(f); } }); this.body = new bricks.FormBody(this, opts); filler.add_widget(this.body); if (! opts.notoolbar) this.build_toolbar(this); this.save_origin_data(); } } bricks.Factory.register('InlineForm', bricks.InlineForm); bricks.Factory.register('Form', bricks.Form);