支持Mocoolka,请点击这里
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);
}
}
});