下面开始设计和完成一个简单的Form的自定义过程。先准备数据,在ModuleModel.js中的data属性下面,加入自定义Form的参数定义,下面的代码中定义了一个新的属性tf_formSchemes,在这个属性下面可以定义多个formScheme,下面的例子中只加入了一个,在formScheme上,加了二个fieldSet,然后在fieldSet下面定义了若干个字段。

// 模块的form方案,可以定义多个方案
tf_formSchemes: [{
tf_schemeOrder: 10,
tf_schemeName: 'form方案1', // 第一个form方案
tf_windowWidth: 600, // form window 的宽度
tf_windowHeight: -1, // 高度-1 即为自动适应高度
// 表头分组
tf_schemeGroups: [{
tf_formGroupId: 1, // id号
tf_formGroupOrder: 10, // 表头分组序号
tf_formGroupName: '工程项目基本信息',
tf_numCols: 1, // 分栏数
// 每一个表头分组下面的字段
tf_groupFields: [{
tf_formFieldOrder: 5,
tf_fieldId: 10100010,
tf_colspan: 1, // 此字段占用的栏数
tf_width: -1,// 宽度,设置-1为 100%
tf_isEndRow: true
// 结束本行,下个字段从新的一行开始排列
}, {
tf_formFieldOrder: 10,
tf_fieldId: 10100020, // 工程项目名称字段
tf_colspan: 1, // 此字段占用的栏数
tf_width: -1,// 宽度,设置-1为 100%
tf_isEndRow: true
// 结束本行,下个字段从新的一行开始排列
}, {
tf_formFieldOrder: 20,
tf_fieldId: 10100030, // 工程项目编码字段
tf_colspan: 1, // 此字段占用的栏数
tf_width: -1,// 宽度,设置-1为 100%
tf_isEndRow: true
// 结束本行,下个字段从新的一行开始排列
}]
}, {
tf_formGroupOrder: 20, // 表头分组序号
tf_formGroupName: '工程项目附加信息',
tf_numCols: 2, // 分栏数
tf_collapsible: true, // 此fieldSet可折叠
tf_collapsed: false, // 默认不折叠
// 每一个表头分组下面的字段
tf_groupFields: [{
tf_formFieldOrder: 10,
tf_fieldId: 10100040
// 建筑面积
}, {
tf_formFieldOrder: 20,
tf_fieldId: 10100050
// 投资总额
}, {
tf_formFieldOrder: 30,
tf_fieldId: 10100060,
tf_isEndRow: true
// 结束本行,下个字段从新的一行开始排列
// 容积率
}, {
tf_formFieldOrder: 40,
tf_fieldId: 10100070
// 计划开工时间
}, {
tf_formFieldOrder: 50,
tf_fieldId: 10100080
// 计划竣工时间
}, {
tf_formFieldOrder: 60,
tf_fieldId: 10100090
// 是否通过验收
}, {
tf_formFieldOrder: 70,
tf_fieldId: 10100100
// 工程方量
}]
}] }]

基础数据准备就绪,就需要创建window了。在module目录下创建一个新的目录window,在 window目录下建立文件BaseWindow.js。

/**
*
* 一个显示、修改、新增的的窗口基类
*
*/
Ext.define('app.view.module.window.BaseWindow', {
extend: 'Ext.window.Window',
alias: 'widget.basewindow', uses: ['app.view.module.form.BaseForm'], layout: 'fit',
maximizable: true,
closeAction: 'hide', bodyStyle: 'padding : 2px 2px 0',
shadowOffset: 30,
layout: 'fit', initComponent: function () {
this.maxHeight = document.body.clientHeight * 0.98; var me = this; this.formScheme = this.getViewModel().get('tf_formSchemes')[0]; // 取得第一个form方案
console.log(this.formScheme);
this.title = this.getViewModel().get('tf_title');
this.glyph = this.getViewModel().get('tf_glyph'); var w = this.formScheme.tf_windowWidth;
var h = this.formScheme.tf_windowHeight;
// 高度为-1表示是自适应
if (w == -1 && h == -1) {
this.width = 600;
this.height = 400;
this.maximized = true;
} else {
if (w != -1)
this.width = Math.min(w, document.body.clientWidth - 2);
if (h != -1)
this.height = Math.min(h, document.body.clientHeight - 2);
};
if (w == -1 && h != -1) { // 宽度最大化
this.width = document.body.clientWidth - 40;
}
this.tools = [{
type: 'collapse',
tooltip: '当前记录导出至Excel'
}]; this.items = [{
xtype: 'baseform',
viewModel: this.getViewModel(),
formScheme: this.formScheme
}]
this.callParent(arguments);
} });

在这个window中根据,配置信息来创建立窗口的大小和title值,然后去创建form。

在module目录中再建立一个form目录,在form目录下建立文件BaseForm.js。在Form中设置好参数后,根据配置信息来创建各个fieldSet。这个类的处理很复杂,要处理正常的fieldSet,还要处理tab ,accordion,以及是否是子模块的Grid的判断,下面的程序里已经简化了。

/**
*
* 一个form窗口的基类,新增、显示、修改、审核、审批等功能继承了这个窗口
*
*/ Ext.define('app.view.module.form.BaseForm', {
extend: 'Ext.form.Panel',
alias: 'widget.baseform', autoScroll: true, buttonAlign: 'center',
initComponent: function () {
var me = this;
this.buttons = [];
this.buttons.push({
text: '关闭',
itemId: 'close',
icon: 'images/button/return.png'
});
me.items = []; var groups = this.formScheme.tf_schemeGroups, hasTab = false;
var hasInTabPanel = false; // 是否有嵌在页里面的tab,
var inTabPanel;
Ext.each(groups, function (group) {
group.tf_numCols = group.tf_numCols || me.formScheme.tf_numCols;
hasTab = hasTab || (group.tf_displayMode == 'tab');
hasInTabPanel = hasInTabPanel
|| (group.tf_displayMode == 'intabpanel');
});
if (hasTab) {
var tabpanel = {
xtype: 'tabpanel',
frame: false,
border: false,
bodyPadding: '5 5 5 5',
items: []
};
groups[0].tf_displayMode = 'tab'; // 如果第一个tab忘了设置
var nowtab; Ext.each(groups, function (group) {
if (group.tf_displayMode == 'tab') {
if (nowtab)
tabpanel.items.push(nowtab);
nowtab = {
xtype: 'container',
title: group.tf_formGroupName,
items: []
};
}
nowtab.items.push(me.createFieldSetOrSubModule(group)); });
tabpanel.items.push(nowtab);
me.items = tabpanel;
} else {
me.bodyStyle = 'padding : 5px 5px 0';
Ext.each(groups, function (group) {
if (group.tf_displayMode == 'intabpanel') {
inTabPanel = {
xtype: 'tabpanel',
frame: false,
border: false,
height: 400,
items: []
};
Ext.apply(inTabPanel, me
.getOtherSetting(group.tf_otherSetting))
me.items.push(inTabPanel);
} else if (group.tf_displayMode == 'intab') {
var t = me.createFieldSetOrSubModule(group);
t.title = group.tf_formGroupName;
inTabPanel.items.push(t)
} else
me.items.push(me.createFieldSetOrSubModule(group)) })
}
me.callParent(arguments);
}, getOtherSetting: function (str) {
if (!str)
return {}
else
return Ext.decode('{' + str + '}', true) }, createFieldSetOrSubModule: function (group) {
var me = this; return Ext.create('app.view.module.form.FieldSet', {
autoScroll: true,
viewModel: this.getViewModel(),
schemeGroup: group,
numCols: group.tf_numCols
}) }, initForm: function () { }, // 不是grid中调用的显示某条记录的信息,可能是其他模块点击namefields来调用的
setRecordId: function (id) {
var me = this;
this.module.model.load(id, {
success: function (record, operation, success) {
// success中的record中返回的raw 数据,是字符串,没有经过decode,要自己转成对象
me.setData(Ext.create(me.module.model, Ext.decode(record.raw)));
}
});
}, setData: function (model) {
this.data = model;
// this.getForm().reset();
if (this.data) {
// Ext.suspendLayouts();
this.getForm().loadRecord(this.data);
// Ext.resumeLayouts(true);
} else
this.getForm().reset();
// 检查form中是否有子模块,如果有则刷新
} });

Form的控件创建好以后,会继续创建每一个FieldSet的内容。在form目录中加入文件FieldSet.js。在这个FieldSet中,暂时还没有加入字段的生成。

/**
*
* 一个form窗口的基类,新增、显示、修改、审核、审批等功能继承了这个窗口
*
*/ Ext.define('app.view.module.form.BaseForm', {
extend: 'Ext.form.Panel',
alias: 'widget.baseform', autoScroll: true, buttonAlign: 'center',
initComponent: function () {
var me = this;
this.buttons = [];
this.buttons.push({
text: '关闭',
itemId: 'close',
icon: 'images/button/return.png'
});
me.items = []; var groups = this.formScheme.tf_schemeGroups, hasTab = false;
var hasInTabPanel = false; // 是否有嵌在页里面的tab,
var inTabPanel;
Ext.each(groups, function (group) {
group.tf_numCols = group.tf_numCols || me.formScheme.tf_numCols;
hasTab = hasTab || (group.tf_displayMode == 'tab');
hasInTabPanel = hasInTabPanel
|| (group.tf_displayMode == 'intabpanel');
});
if (hasTab) {
var tabpanel = {
xtype: 'tabpanel',
frame: false,
border: false,
bodyPadding: '5 5 5 5',
items: []
};
groups[0].tf_displayMode = 'tab'; // 如果第一个tab忘了设置
var nowtab; Ext.each(groups, function (group) {
if (group.tf_displayMode == 'tab') {
if (nowtab)
tabpanel.items.push(nowtab);
nowtab = {
xtype: 'container',
title: group.tf_formGroupName,
items: []
};
}
nowtab.items.push(me.createFieldSetOrSubModule(group)); });
tabpanel.items.push(nowtab);
me.items = tabpanel;
} else {
me.bodyStyle = 'padding : 5px 5px 0';
Ext.each(groups, function (group) {
if (group.tf_displayMode == 'intabpanel') {
inTabPanel = {
xtype: 'tabpanel',
frame: false,
border: false,
height: 400,
items: []
};
Ext.apply(inTabPanel, me
.getOtherSetting(group.tf_otherSetting))
me.items.push(inTabPanel);
} else if (group.tf_displayMode == 'intab') {
var t = me.createFieldSetOrSubModule(group);
t.title = group.tf_formGroupName;
inTabPanel.items.push(t)
} else
me.items.push(me.createFieldSetOrSubModule(group)) })
}
me.callParent(arguments);
}, getOtherSetting: function (str) {
if (!str)
return {}
else
return Ext.decode('{' + str + '}', true) }, createFieldSetOrSubModule: function (group) {
var me = this; return Ext.create('app.view.module.form.FieldSet', {
autoScroll: true,
viewModel: this.getViewModel(),
schemeGroup: group,
numCols: group.tf_numCols
}) }, initForm: function () { }, // 不是grid中调用的显示某条记录的信息,可能是其他模块点击namefields来调用的
setRecordId: function (id) {
var me = this;
this.module.model.load(id, {
success: function (record, operation, success) {
// success中的record中返回的raw 数据,是字符串,没有经过decode,要自己转成对象
me.setData(Ext.create(me.module.model, Ext.decode(record.raw)));
}
});
}, setData: function (model) {
this.data = model;
// this.getForm().reset();
if (this.data) {
// Ext.suspendLayouts();
this.getForm().loadRecord(this.data);
// Ext.resumeLayouts(true);
} else
this.getForm().reset();
// 检查form中是否有子模块,如果有则刷新
} });

以过以上步骤,加入了 window-form-fieldset的三级控件的创建,下面来显示一下结果。在GridToolbar.js中,给修改按钮加个事件:

{
text : '修改',
glyph : 0xf044,
itemId : 'edit',
handler : 'editRecord'
}

在ModuleController.js中加入函数:

editRecord : function(button) {
var window = Ext.widget('basewindow',{
viewModel : this.getView().getViewModel()
});
window.show();
},

在Module.js 的uses 中加入 'app.view.module.window.BaseWindow',这样就可以运行了。

下面一节将会加入不同种类的field。

22、手把手教你Extjs5(二十二)模块Form的自定义的设计[1]的更多相关文章

  1. 21、手把手教你Extjs5(二十一)模块Form的自定义的设计

    前面几节完成了模块Grid的自定义,模块Form自定义的过程和Grid的过程类似,但是要更复杂一些.先来设计一下要完成的总体目标. 1、可以有多个Form方案,对应于显示.新增.修改.审核.审批等功能 ...

  2. 23、手把手教你Extjs5(二十三)模块Form的自定义的设计[2]

    在本节中将要加入各种类型的字段,在加入字段的时候由于可以一行加入多个字段,因此层次结构又多了一层fieldcontainer.form里面的主要层次结构如下: form -- fieldSet -- ...

  3. 12、手把手教你Extjs5(十二)执行菜单命令在tabPanel中显示模块

    上面设计好了一个模块的主界面,下面通过菜单命令的执行来把这个模块加入到主界面当中.在MainModule.js中有一个函数,生成了当前的菜单数据: // 根据data.systemMenu生成菜单条和 ...

  4. 13、手把手教你Extjs5(十三)模块字段和Grid列的定义[1]

    这一节加入模块自定义字段,并根据这些字段生成model.然后再定义grid中的分组和列.从这一切开始真正进入到了模块自定义的节奏当中,代码的复杂度和技巧性也大大提高.先从模块字段的自定义开始.先看一下 ...

  5. 24、手把手教你Extjs5(二十四)模块Form的自定义的设计[3]

    自定义的Form已经可以运行了,下面改一下配置,把Form里面的FieldSet放在Tab之下.修改一下ModuleModel.js中的data下的tf_FormSchemes下的方案,增加一个属性. ...

  6. 15、手把手教你Extjs5(十五)各种Grid列的自定义渲染

    Grid各列已经能够展示出来了.列的类型包括字符型,整型,浮点型,货币型,百分比型,日期型和布尔型,我自定义了各种类型的渲染样式: 1.整型:标题栏居中,数值靠右显示,正数颜色为蓝色,负数颜色为红色, ...

  7. 19、手把手教你Extjs5(十九)模块Grid的其他功能的设想

    经过对自定义模块和Grid的设计和编码,现在已经能对一个有配置信息的模块来生成界面并进行一些简单的CURD操作.由于这是一个全解释性的前台的架构,因此你想到的任何新主意都可以放到所有的模块中. 比如对 ...

  8. 18、手把手教你Extjs5(十八)模块记录的拖放删除、拖放复制新增

    网页当中的拖放(drag-drop)是比较有趣的操作,extjs5中很好的封装了拖放的动作,也有各种类来支持,但是要学好“拖放”这个东西真是很难,特别是象我这样英语不好的人,看不太懂官网上的说明,做一 ...

  9. 16、手把手教你Extjs5(十六)Grid金额字段单位MVVM方式的选择

    这一节来完成Grid中的金额字段的金额单位的转换.转换旰使用MVVM特性,总体上和控制菜单的几种模式类似.首先在目录app/view/main/menu下建立文件Monetary.js,用于放金额单位 ...

随机推荐

  1. Batch Sort

    Batch Sort time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  2. AJax的异步请求

    AJax的处理过程 1、传统的Web请求过程: 一般的 Web 应用程序中,用户填写表单字段并单击 Submit 按钮.然后整个表单发送到服务器,服务器将它转发给处理表单的脚本(通常是 PHP 或 J ...

  3. Swift の 函数式编程

    Swift 相比原先的 Objective-C 最重要的优点之一,就是对函数式编程提供了更好的支持. Swift 提供了更多的语法糖和一些新特性来增强函数式编程的能力,本文就在这方面进行一些讨论. S ...

  4. SAX,DOM,JAXP,JDOM,DOM4J比较

    dom,sax,jdom,dom4j的技术特点: 1: DOMDOM 是用与平台和语言无关的方式表示 XML 文档的官方 W3C 标准.DOM 是以层次结构组织的节点或信息片断的集合.这个层次结构允许 ...

  5. android apk jarsigner 签名打包

    cmd 命令符打包: 规则:  jarsigner -verbose -keystore 签名路径 -signedjar 签名后的apk存放路径  未签名的apk 签名文件的别名 项目如我的项目是: ...

  6. CodeForces 678D Iterated Linear Function

    简单矩阵快速幂. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm& ...

  7. 用Visual Studio 2015 编写驱动之前一定要注意的问题!!!

    如果你确定要使用Visual Studio 2015 编写驱动,那么在你安装Visual Studio 2015 和WDK之前,一定一定要注意一件事情,那就是确保SDK和WDK版本保持一致,切记切记! ...

  8. PHP学习笔记之数组篇

    摘要:其实PHP中的数组和JavaScript中的数组很相似,就是一系列键值对的集合.... 转载请注明来源:PHP学习笔记之数组篇   一.如何定义数组:在PHP中创建数组主要有两种方式,下面就让我 ...

  9. git bash退回上一个文件夹

    cd ..\ a@w3311 MINGW32 /f/Projects/crm (master) $ cd..\ > bash: cd..: command not found a@w3311 M ...

  10. opencv 相关一个很好的博客

    http://blog.csdn.net/zouxy09/article/category/1218765 图像卷积与滤波的一些知识点 图像卷积与滤波的一些知识点zouxy09@qq.comhttp: ...