https://code.csdn.net/2013ossurvey#gitvote32
屏幕生成器FORM有两个作用
一个是把窗体字段拖到屏幕中进行排列,在设计时使用,最后保存成模型的一部分。
二是在设计后做为输入、输出的UI
FORM生成由MKEDITPANEL、和组件组成,组件就是每个字段使用到的控件。
生成FORM由布局和组件两部分组成。
布局现在只支持一种vbox hbox
组件有几个关键参数:位置决定组件出现在布局的哪里,宽度决定组件的宽度,条件决定一个字段生成几个组件,比如大于小于就生成两个组件
这几个因为跟屏幕密切相关就保存在模型的字段中。
屏幕显示标签、屏幕用到哪种组件保存在模型的列中,因为它们不会因屏幕发生改变而改变
下面是核心的代码类MKEDITPANEL
代码用到extjs库
/* ************************************************************************* * Contact: http://www.mocoolka.com * GNU General Public License Usage * This file may be used under the terms of the GNU General Public License version 3.0 as * published by the Free Software Foundation and appearing in the file LICENSE included in the * packaging of this file. * Please review the following information to ensure the GNU General Public License version 3.0 * requirements will be met: http://www.gnu.org/copyleft/gpl.html. * The Original Code is Mocoolka Group. * The Initial Developer of the Original Code is MoCoolKa SLU * All portions are Copyright (C) 2012-2013 MoCoolKa SLU * All Rights Reserved. * Contributor(s): ______________________________________. ************************************************************************ */ /* ************************************************************************* *FORM生成,根据模型生成标准的FORM。在模型中已经保存了屏幕布局和每个字段所使用的组件 *在本类中就是用循环的方式取出每个组件,按照模型中定义的布局,自动排列顺序和位置 * ************************************************************************ */ var required = '<span style="color:red;font-weight:bold" data-qtip="Required">*</span>'; Ext.define('Mocoolka.component.MKEditPanel', { extend: 'Ext.form.Panel', xtype: 'mkeditpanel', requires: ['Mocoolka.ux.MKFieldDropZone', 'Mocoolka.model.MKCheckMenu', 'Mocoolka.component.MKTree' , 'Mocoolka.store.MKMenus', 'Mocoolka.component.MKToolbar', 'Mocoolka.model.MKMenu', 'Mocoolka.component.MKSearchField', 'Mocoolka.component.MKComboBox' , 'Mocoolka.component.MKOrderField', 'Mocoolka.component.MKIconSelect'], MKEditModel: 'Edit', fieldDefaults: { msgTarget: 'side', //labelWidth: 75 }, isBorder: true, fieldsetMargin: "10 10 0 10", fieldsetPading: 5, fieldsetCollapsible: true, containerPading: 1, containerMargin: 0, fieldPading:2, initComponent: function () { var me = this; //提示初始化 Ext.QuickTips.init(); //模型对象 var tab=this.mktab; //在编辑中,也就是在设计时使用 if (me.MKEditModel == 'Edit') { //建立延时任务 me.beginrefresh = new Ext.util.TaskRunner().newTask({ run: me.newbuild1, interval: 1000, repeat: 1 }); me.task = new Ext.util.DelayedTask(function () { //重画页面 me.newbuild1(); }); me.begintask = function () { me.task.delay(500); }; } if (tab) { //查询条件 if (me.mktabtype == 'Manager') { //取出查询条件下使用的字段 me.fields = tab.getMKFieldStore("Manager"); me.fieldsetMargin= "0 10 0 10"; } else //取出编辑屏幕使用的字段 me.fields = tab.getMKFieldStore("Edit"); } selectcontrol = null; me.callParent(); if (tab) { //根据模型,刷新屏幕 me.refresh(me); } //增加4个事件 //select 在屏幕中选中一个组件 //update 组件值发生改变 //positionchange 位置发生变化 //mkfieldchange 组件值发生改变 me.addEvents( "select", "update", "positionchange", "mkfieldchange" ) }, init: function (tab) { var me = this; me.tabstore = tab; //如果在设计中 if (me.MKEditModel == 'Edit') { me.beginrefresh = new Ext.util.TaskRunner().newTask({ run: me.newbuild1, interval: 1000, repeat: 1 }); me.task = new Ext.util.DelayedTask(function () { me.newbuild1(); }); me.begintask = function () { me.task.delay(500); }; console.log("Edit"); } if (me.mktabtype == 'Manager') { me.fields = tab.FieldList(); } else me.fields = tab.getMKFieldStore("Edit"); selectcontrol = null; me.newbuild(); //在设计中 if (me.MKEditModel == 'Edit') { //单击事件,判断是否单击到一个组件,如果是,点燃选择事件 me.body.on('click', function (e, t) { var i = t.id.lastIndexOf('-'); name = t.id.substring(0, i); var o = me.down("#" + name); if (o != null && o.mkfield != null) { me.activecontrol(o.name); me.fireEvent('select', o.mkfield); } }, null, [{ delegate: 'x-form-item' }, ]); } }, //containerContextMenu: function (view, e) { // console.log(view); //}, //初始化 begin: function () { var me = this; me.init(me.tabstore); }, //组件缺省配置 fieldDefaults: { labelAlign: 'right', }, //缺省布局, layout: { type: 'vbox', align: 'stretch' }, border: false, controlitems: [], //设置组件名称,如果是查询条件,增加用的到查询条件 setstandactcontrol: function (name, condition) { if (this.mktabtype == 'Manager') { setactcontrol(name + "_" + condition); } else setactcontrol(name); }, //不激活组件,从以前激活的组件上去掉可拖动宽度组件,改变为普通边框 unactivecontrol: function () { var me = this; if (me.selectname && me.selectcontrol != null) { me.selectcontrol.inputEl.setStyle("borderColor", me.selectcontrol.backupcolor); if (me.customResizer) { me.customResizer.destroy(); } me.selectname = null; me.selectcontrol = null; } }, //激活组件 activecontrol: function (name) { var me = this; //如果是当前激活,不做处理 if (me.selectname == name && me.selectcontrol != null) return; //不激活当前焦点组件 me.unactivecontrol(); //查找激活组件 var o = me.down('field[name="' + name + '"]'); //设置为当前焦点组件 me.selectcontrol = o; if (me.selectcontrol) { me.selectname = name; //改变边框为激活 me.selectcontrol.backupcolor = me.selectcontrol.inputEl.getStyle("borderColor"); me.selectcontrol.inputEl.setStyle("borderColor", 'red'); //组件可以拖动宽度 me.customResizer = Ext.create('Ext.create', 'Ext.resizer.Resizer', { target: me.selectcontrol.id, pinned: false, minWidth: 20, minHeight: 10, widthIncrement: 5, listeners: { resize: function (control, width, height, e, eOpts) { var con = me.down("#" + control.originalTarget.id); con.mkfield.set("Width", width); con.mkfield.commit(); var form = con.up('mkeditpanel'); form.fireEvent('update', con.mkfield); form.newbuild(); }, resizedrag: function (control, width, height, e, eOpts) { var con = me.down("#" + control.originalTarget.id); var panel = con.up("mkeditpanel"); panel.selectcontrol.Width = (width); }, }, dynamic: true, handles: 'e' // shorthand for 'n s e w ne nw se sw' }); } }, //刷新 newbuild: function () { var me = this; //设计中 if (me.MKEditModel == "Edit") { //暂时挂起事件响应,为了提高渲染效率 me.suspendEvents(false); } //删除以前组件 me.deletedata(me); //重新生成组件 me.refresh(me); if (me.MKEditModel == "Edit") { me.resumeEvents(); // Ext.resumeLayouts(true); } //点燃位置改变事件 me.fireEvent('positionchange'); }, //清空组件占用的内存 beforeDestroy: function () { var me = this; me.deletedata(me); me.callParent(); }, //删除屏幕组件 deletedata: function (me) { me.unactivecontrol(); if (selectcontrol) selectcontrol.destroy(); if (me.beginrefresh) me.beginrefresh.destroy(); me.removeAll(true); }, newbuild1: function () { var me = this; console.log(me); me.deletedata(me); me.refresh(me); me.fireEvent('positionchange'); }, fields: undefined, beginrefresh: undefined, //重画组件 refresh: function (me) { //模型 var tab = me.mktab; //模型中用到的字段 var fields = me.fields; //按位置排序 sortbyname(fields, "Position"); //建立组件集合 var item1 = me.CreateFormItems(tab, fields, "test", me.mktabtype, "box", me.MKEditModel); //增加到屏幕上 me.add(item1); }, //建立组件集合 //tab:模型数据,fields:当前字段集合,defaultGroupText:缺省的分组标题,ifFind是否查询条件,layout:布局,EditModel CreateFormItems: function (tab, fields, defaultGroupText, ifFind, layout, EditModel) { var gridfields = ""; var rootItems = []; var first = true; //遍历字段 for (var i = 0; i < fields.getCount() ; i++) { var curr; var box; var field = fields.getAt(i); //不显示位置的跳过 if (field.get("Position") <= 0 || field.get("Position") == null || field.get('IsHide') == true) { continue; } //没通过校验的跳过 if (!mkmodelutil.verfiyfield(field)) continue; //列对象 var col = field.data.Column; //如果是分组框,先增加分组框,把增加的分组框设置为当前分组框 if (field.get('FieldGroup') != null && field.get('FieldGroup') != "") { if (layout == "box") { curr = this.createboxFieldset(field.get('FieldGroup'), EditModel); box = this.createboxcontainer(); curr.items.push(box); rootItems.push(curr); } else { curr = this.createFieldset(field.get('FieldGroup'), 4, EditModel); rootItems.push(curr); } first = true; } if (curr == null) { if (layout == "box") { curr = this.createboxFieldset(field.get('FieldGroup'), EditModel); box = this.createboxcontainer(); curr.items.push(box); rootItems.push(curr); first = true; } else { curr = this.createFieldset(field.get('FieldGroup'), 4, EditModel); rootItems.push(curr); first = true; } } //得到过滤条件,如果过滤条件为大于小于等涉及到两个条件的,增加两个组件,为查询条件FORM使用 var filter = field.get("FilterCondition"); var fieldControl; if (filter != null) { if (filter.length > 1) { fieldControl = []; var filters = filter.split(","); for (var k=0;k< filters.length;k++) { var f = filters[k]; var fieldControl1 = this.GenField(field, tab, ifFind, layout, EditModel); fieldControl1.condition = f; if (k != 0) { fieldControl1.width = fieldControl1.width - fieldControl1.labelWidth + 20; fieldControl1.labelWidth = 20; fieldControl1.fieldLabel = "---"; fieldControl1.labelSeparator = ""; } fieldControl.push(fieldControl1); } } else { fieldControl = this.GenField(field, tab, ifFind, layout, EditModel); if (fieldControl.length > 0) { for (var y in fieldControl) { fieldControl[y].condition = filter; } } else fieldControl.condition = filter; } } else { fieldControl = this.GenField(field, tab, ifFind, layout, EditModel); } if (layout == "box") { //如果是新行,建立一个新的容器,新加组件加到新容器中 if (field.get('IsNewLine') && first == false) { box = this.createboxcontainer(); curr.items.push(box); } if (fieldControl.length == null) { box.items.push(fieldControl) } else { for (var j = 0; j < fieldControl.length; j++) { box.items.push(fieldControl[j]); } } } else { if (fieldControl.length == null) { curr.items.push(fieldControl) } else { for (var z = 0; j < fieldControl.length; j++) { curr.items.push(fieldControl[z]); } } } first = false; }; return rootItems; }, //根据字段建立组件 GenField: function (field, tab, ifFind, layout, EditModel) { //列对象 var col = field.get('Column'); //相关列 var relationcolumn = col.get("RelationColumn"); //是否只读 var IsReadOnly = col.get("IsReadOnly") == true || field.get("IsReadOnly") == true; var type = col.get('ReferenceID'); if (relationcolumn != null && relationcolumn.length > 0) { col.set("ComboxID", "System.RelationColumn"); type = "ComboBox"; } var re = {}; var name; name = field.get('Name'); //如果隐藏,跳过 if (field.get('IsHide') == true) { return ; } //下拉框 if (type == 'ComboBox') { var re = { xtype: 'mkcombobox', mkfield: field, }; } //下拉框选择名字 else if (type == 'ComboBoxByName') { var re = { xtype: 'mkcombobox', mkfield: field, isName:true, }; } //弹出框 else if (type == 'Search') { var re = mkviewutil.getSelectDialog(col); } //顺序多选框 else if (type == 'MKOrderField') { var re = { xtype: 'mkorderfield', mkfield: field, }; } //图标框 else if (type == 'IconSelect') { re = { xtype: 'mkiconselect', mkfield: field, }; } //字体框 else if (type == 'FontSelect') { re = { xtype: 'mkfontselect', mkfield: field, }; } //密码组件 else if (type == 'Password') { re = { xtype: 'textfield', inputType: 'password', }; } //整型 else if (type == 'Int') { re.xtype = 'numberfield'; if (EditModel != "Edit") { if (col.get('ValueMax') != 0 && IsReadOnly == false) re.maxValue = col.get('ValueMax'); if (col.get('ValueMin') != 0 && IsReadOnly == false) re.minValue = col.get('ValueMin'); } re.allowDecimals = false; } //付点 else if (type == 'Decimal') { if (EditModel != "Edit") { if (col.get('ValueMax') != 0 && IsReadOnly == false) re.maxValue = col.get('ValueMax'); if (col.get('ValueMin') != 0 && IsReadOnly == false) re.minValue = col.get('ValueMin'); } re.allowDecimals = true; re.xtype = 'numberfield'; } //时间 else if (type == 'DateTime') { re.xtype = 'datefield'; var format = col.get("Vformat"); if (format == null || format.length==0) { format = DefaultShortDateFormat; } re.submitFormat = DefaultLongDateFormat, re.format = format;//'Y-m-d'; } //备注 else if (type == 'Remark') { re.xtype = 'textareafield'; } //复选 else if (type == 'CheckBox') { if (ifFind == 'Manager') { re = mkviewutil.getCheckedCombo(col); } else { re.xtype = 'checkboxfield'; re.inputValue = true; re.uncheckedValue = false; } } //单选 else if (type == 'Radio') { re.xtype = 'radiofield'; } //多选树 else if (type == 'MultiTree') { re.xtype = 'hiddenfield'; } //隐藏 else if (type == 'Hidden') { re.xtype = 'hiddenfield'; } //文本 else { re = { xtype: 'textfield', }; } re.fieldLabel = field.get('Description'); re.labelAlign = "right"; //值改变事件,执行模型脚本 re.listeners = { change: { fn: function (field, newValue, oldValue, eOpts) { var col = this.mkfield.get("Column"); var script = col.get('ValueChangeScript'); var form = this.up("mkeditpanel"); form.fireEvent('mkfieldchange', form, field, newValue, oldValue, eOpts); if (script != null && script.length > 0) { eval(script); } } }, }; if (EditModel != "Edit") { if (ifFind == 'Edit') { //必填 if ((col.get("IsMandatory") || field.get('IsMandatory')) && IsReadOnly == false) { re.allowBlank = false; re.afterLabelTextTpl = required; } if (IsReadOnly == true) { re.readOnly = true; } if (col.get("FieldLength") > 0 && IsReadOnly == false) { re.maxLength = col.get("FieldLength"); } re.mkautoSelect = true; } } re.name = name; re.mkfield = field; if (type != 'CheckBox' || ifFind == 'Manager') re.labelWidth = field.get('LabelWidth'); //柔度设置 if (field.get('Flex') > 0) { re.flex = field.get('Flex'); } if (layout == "box") { // re.width = 100; //if (ifFind == '101') { //宽度设置 if (field.get('Width') <= 0) { if (type != 'CheckBox' || ifFind == 'Manager') // re.width = 100; //else re.width = 150; } else { if (type != 'CheckBox' || ifFind == 'Manager') re.width = field.get('Width'); } } re.padding = this.fieldPading; //多选树组件 if (type == 'MultiTree') { var cons = []; var url = rooturl + '?request=System.Model.ComboBox&&requestaction=getvalues&&comboxid=' + col.get('ComboxID'); var displayFields = col.get('ComboxColumnNames'); var displayFieldarray = displayFields.split(','); var firstdisplayField = displayFieldarray[0]; var model = buildEntityTreeModel('mk', displayFields) var store = MK.TreeManager.createTreeStore(url, model); console.log(firstdisplayField); var add = { xtype: 'mktree', store: store, height: 300, mktext: field.get('Description'), mkfield:field, mkdataIndex: firstdisplayField, width:600,//flex: 1, columns: [ { xtype: 'treecolumn', text: field.get('Description'), head: '', flex: 1 } ], dockedItems: [], }; cons.push(add); cons.push(re); return cons; } //弹出框 else if (type == 'Search') { var cons = []; var hidee = { xtype: 'hiddenfield', name: re.name }; re.name = re.name + "Name"; cons.push(hidee); cons.push(re); console.log(cons); return cons; } return re; }, //建立分组框 createFieldset: function (mytitle, mycols, EditModel) { re = { xtype: 'fieldset', title: mytitle, defaultType: 'textfield', layout: { type: 'table', columns: mycols }, items: [], } if (EditModel == "Edit") //拖动组件 re.plugins = [Ext.create('Mocoolka.ux.MKFieldZone')]; return re; }, createboxFieldset: function (mytitle, EditModel) { re = { xtype: 'fieldset', defaultType: 'textfield', collapsible: this.fieldsetCollapsible, border: this.isBorder, layout: 'anchor', margin: this.fieldsetMargin, padding: this.fieldsetPading, defaults: { anchor: '100%' }, items: [], }; if (EditModel == "Edit") { re.plugins = [Ext.create('Mocoolka.ux.MKFieldZone')]; re.listeners = { afterrender: function (form) { var cfg = { shadow: false, completeOnEnter: true, cancelOnEsc: true, updateEl: true, ignoreNoChange: true }, height = 80; var labelEditor = Ext.create('Ext.Editor', Ext.apply({ autoSize: { width: 'field' }, height: height, offsets: [0, (Ext.isIEQuirks ? 0 : 2)], alignment: 'l-l', fieldset: this, listeners: { beforecomplete: function (ed, value) { if (value.charAt(value.length - 1) != ':') { ed.setValue(ed.getValue() + ':'); } var form = ed.fieldset.up("mkeditpanel"); if (form.selectcontrol) { form.selectcontrol.mkfield.set('Description', ed.getValue().substring(0, ed.getValue().length - 1)); form.selectcontrol.mkfield.commit(); form.fireEvent('update', form.selectcontrol.mkfield); } return true; } }, field: { width: 80, name: 'labelfield', allowBlank: false, xtype: 'textfield', selectOnFocus: true, maxLength: 20, enforceMaxLength: true } }, cfg)); var textEditor = Ext.create('Ext.Editor', Ext.apply({ autoSize: { width: 'field' }, height: height, offsets: [0, (Ext.isIEQuirks ? 0 : 2)], alignment: 'l-l', listeners: { beforecomplete: function (ed, value) { if (value.charAt(value.length - 1) != ':') { ed.setValue(ed.getValue() + ':'); } var con = me.down("#" + this.Items[0].id); var form = con.up("mkeditpanel"); if (form.selectcontrol) { form.selectcontrol.mkfield.set('Description', ed.getValue()); form.selectcontrol.mkfield.commit(); form.fireEvent('update', form.selectcontrol.mkfield); } return true; } }, field: { width: 80, name: 'labelfield', allowBlank: false, xtype: 'sliderfield', value: 50, selectOnFocus: true, maxLength: 20, enforceMaxLength: true } }, cfg)); form.body.on('dblclick', function (e, t) { labelEditor.startEdit(t); console.log('dblclick'); labelEditor.field.focus(50, true); }, null, [{ delegate: 'label.x-form-item-label' }, ]); } }; } if (this.isBorder) re.title = mytitle; return re; }, //建立容器 createboxcontainer: function () { return { xtype: 'container', margin: this.containerMargin, padding: this.containerPading, layout: 'hbox', combineErrors: true, items: [] } }, //组件毁坏 onDestroy: function () { var me = this; if (me.beginrefresh) { Ext.destroy(me.beginrefresh); } } });