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

现在加入fieldcontainer的生成器的文件,在factory中加入文件FieldContainerFactory.js

/**
* 字段容器factory
*/
Ext.define('app.view.module.factory.FieldContainerFactory', { statics: { getContainer: function (container, module, formtype) { var result = {
xtype: 'fieldcontainer',
layout: 'hbox',
margin: '0 0 0 0',
items: []
};
for (var i in container) {
var field = container[i];
// 如果是空的位置
if (field.spacer) {
result.items.push({
xtype: 'fieldcontainer',
layout: 'anchor',
margin: '0 0 0 0',
flex: field.flex
});
} else {
var fieldDefine = module.getFieldDefine(field.tf_fieldId); var f = app.view.module.factory.FormFieldFactory.getField(fieldDefine,
field, formtype, module); var c = {
xtype: 'fieldcontainer',
layout: (f.moduleName)
? (field.tf_width != -1 ? 'table' : 'hbox')
: 'anchor',
flex: field.tf_colspan,
items: []
};
if (c.layout == 'hbox')
c.margin = '0 0 5 0';
c.items.push(f); result.items.push(c);
}
}
return result;
}
}
});

现在要加入最后一个field的生成器,FormFieldFactory.js,此文件敢放在factory目录之下。

/**
* 用于生成form中的每一个field
*/ Ext.define('app.view.module.factory.FormFieldFactory', { statics: {
labelDefaultWidth: 92,
dateDefaultSize: 14,
integerDefaultSize: 10,
moneyDefaultSize: 14,
/**
* 根据module定义,formField的定义,formtype来返回一个field的定义
*/
getField: function (fieldDefine, formField, formtype, module) { var field = {
name: fieldDefine.tf_fieldName,
fieldLabel: formField.fieldLabel
|| (formField.labelAhead ? formField.labelAhead : '')
+ fieldDefine.tf_title.replace(new RegExp('--', 'gm'), ''),
labelAlign: formField.labelAlign || 'right',
labelWidth: formField.labelWidth || this.labelDefaultWidth,
behindText: formField.behindText || fieldDefine.behindText
};
if (field.behindText && field.behindText == ' ')
delete field.behindText; if (formField.labelWidth)
field.labelWidth = formField.labelWidth;
if (formField.hideLabel)
field.hideLabel = true;
// 如果是隐藏字段
if (this.getIsHidden(fieldDefine, formField)) {
Ext.apply(field, {
xtype: 'hiddenfield'
});
return field;
} Ext.apply(field, this.getFieldXType(fieldDefine, field));
if (formField.tf_width == -1) {
delete field.size;
field.anchor = '100%';
} // 是否是必添字段
if (fieldDefine.tf_isRequired)
Ext.apply(field, {
allowBlank: false
}); return field;
}, /**
* 判断字段类型
*/
getFieldXType: function (fieldDefine, field) { switch (fieldDefine.tf_fieldType) {
case 'Date':
return {
size: this.dateDefaultSize,
format: 'Y-m-d',
xtype: 'datefield',
submitFormat: 'Y-m-d'
}
case 'Datetime':
return {
size: this.dateDefaultSize,
format: 'Y-m-d H:i:s',
xtype: 'datetimefield'
}
case 'Boolean':
return {
xtype: 'checkboxfield',
inputValue: 'true'
};
case 'Integer':
return {
minValue: -9999999999,
maxValue: 9999999999,
fieldStyle: "text-align:right",
size: this.integerDefaultSize,
xtype: 'numberfield',
enableKeyEvents: true,
listeners: {
keydown: function (field, e, eOpts) {
if (e.getKey() == Ext.EventObject.ENTER) {
var f = field.nextSibling('field[readOnly=false]');
if (!!f)
f.focus();
return false;
}
}
}
};
case 'Double':
return {
size: this.moneyDefaultSize,
hideTrigger: true,
xtype: 'numberfield',
behindText: '元' };
case 'Float':
return {
minValue: -9999999999,
maxValue: 9999999999,
size: this.moneyDefaultSize,
hideTrigger: true,
xtype: 'numberfield'
};
case 'Percent':
return {
size: this.moneyDefaultSize,
xtype: 'numberfield',
// behindText : '%',
percent: true
};
case 'String':
var len = fieldDefine.l;
if (len == 0 || len > 100)
return {
maxLength: len == 0 ? Number.MAX_VALUE : len,
enforceMaxLength: true,
anchor: '100%',
grow: true,
growMax: 200,
growMin: 40,
xtype: 'textareafield'
}
else
return {
maxLength: len,
size: len,
enforceMaxLength: true,
xtype: 'textfield',
enableKeyEvents: true,
listeners: {
keydown: function (field, e, eOpts) {
if (e.getKey() == Ext.EventObject.ENTER) {
var f = field.nextSibling('field[readOnly=false]');
if (!!f)
f.focus();
return false;
}
}
}
}; }
}, /**
* 判断是否是hidden字段
*/
getIsHidden: function (fieldDefine, formField) {
return (fieldDefine.tf_isHidden || formField.tf_isHidden)
}
}
});

上面的字段生成factory中省略了combo和选择父级字段属性的操作,只生成字符型,数值型,布尔型和日期型的内容。

现在还要修改一下fieldSet.js中的内容,使其加入FieldContainer,文件重新发布一下:

/**
*
* 生成form中的一个fieldSet的类
*
*/
Ext.define('app.view.module.form.FieldSet', {
extend: 'Ext.form.FieldSet',
alias: 'widget.formfieldset', requires: ['app.view.module.factory.FieldContainerFactory',
'app.view.module.factory.FormFieldFactory'], defaultType: 'textfield',
defaults: {},
layout: 'anchor',
config: {
module: undefined, //  此模块的module定义
schemeGroup: undefined, // 定义了此fieldSet的属性以及下面需要加的字段
numCols: undefined,
formtype: undefined
}, initComponent: function () {
this.title = this.schemeGroup.tf_formGroupName;
this.collapsible = this.schemeGroup.tf_collapsible;
this.collapsed = this.schemeGroup.tf_collapsed; this.items = []; var containers = []; // 要计算一下有多少个container,如果col=2,那么二个一换行,或者指定换行
var hiddens = []; // 隐藏的字段
var container = [];
var c = 0; for (var i in this.schemeGroup.tf_groupFields) {
var field = this.schemeGroup.tf_groupFields[i];
var fieldDefine = this.getViewModel()
.getFieldDefine(field.tf_fieldId);
// 如果是隐藏字段,那么就直接放在隐藏字段的数组里
if (fieldDefine && fieldDefine.tf_isHidden) {
hiddens.push(field);
continue;
}
} for (var i in this.schemeGroup.tf_groupFields) {
var field = this.schemeGroup.tf_groupFields[i];
var fieldDefine = this.getViewModel()
.getFieldDefine(field.tf_fieldId);
if (fieldDefine && fieldDefine.tf_isHidden) {
continue;
}
// 设置tf_colspan如果是0,那么置为1,如果大于tf_colspan,置为tf_colspan
field.tf_colspan = field.tf_colspan ? field.tf_colspan : 1;
if (field.tf_colspan > this.numCols)
field.tf_colspan = this.numCols;
// 如果加上这一行,超出了numCols,那么就要分二行了
if (c + field.tf_colspan > this.numCols) {
if (this.numCols - c > 0)
container.push({
spacer: true,
flex: this.numCols - c
});
containers.push(container);
container = [];
container.push(field);
c = field.tf_colspan;
} else {
container.push(field);
c += field.tf_colspan;
if (c >= this.numCols || field.tf_isEndRow) {
if (this.numCols - c > 0)
container.push({
spacer: true,
flex: this.numCols - c
});
c = 0;
containers.push(container);
container = [];
}
}
}
if (container.length > 0)
containers.push(container);
// 生成每一个container ,一个container中可以放置若干个字段,如果分栏是3,那就放3个
for (var i in containers) {
this.items.push(app.view.module.factory.FieldContainerFactory
.getContainer(containers[i], this.getViewModel(), this.formtype));
} // 加入隐藏的字段
for (var i in hiddens) {
var field = hiddens[i];
var fieldDefine = this.module.getFieldDefine(field.tf_fieldId);
var f = app.view.module.factory.FormFieldFactory.getField(
fieldDefine, field, this.formtype);
this.items.push(f);
} this.callParent(arguments);
}
})

BaseForm.js中也对buttons重新定义一下,加入了一个保存按钮。

this.buttons.push({
text: '保存',
itemId: 'save',
glyph: 0xf0c7
}, {
text: '关闭',
itemId: 'close',
glyph: 0xf148,
handler: function (button) {
button.up('window').hide();
}
});

ModuleController.js中的editRecord事件的处理函数也修改,增加了调用当前选中Grid中记录的函数。

editRecord : function(button) {
var window = Ext.widget('basewindow', {
viewModel : this.getView().getViewModel()
});
window.down('baseform').setData(this.getView().down('modulegrid')
.getSelectionModel().getSelection()[0]);
window.show();
},

经过以上步骤,可以看到一个修改form的窗口如下,窗口的高度是自动适应的。

至此,一个根据form参数自定义的基本界面搭建完成了。对于简单的应用这样搭建已经足够了,对于复杂的field的配置,你可以把他描述成属性值的配置,然后再入解释执行的代码,这样你可以完成更多的定制功能。比如说现在的字段建筑面积后面的“平米”如何加入,如何加入各种类型的combo字段等等,我现在的这个讲解只提供一个自定义的思路,有更多想法还要自己去实现。

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

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

    下面开始设计和完成一个简单的Form的自定义过程.先准备数据,在ModuleModel.js中的data属性下面,加入自定义Form的参数定义,下面的代码中定义了一个新的属性tf_formScheme ...

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

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

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

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

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

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

  5. 2、手把手教你Extjs5(二)项目中文件的加载过程

    上一节中用sencha工具自动创建了一个项目,并且可以在浏览器中查看.现在我们来看看js类加载过程.如下图所示: 1、首先:浏览器中输入 localhost:1841 ,调用 index.html; ...

  6. 20、手把手教你Extjs5(二十)模块Grid的多列表方案

    对于有很多字段的模块在一个grid中显示所有的字段,会显得很臃肿,对于不同的用户其侧重的字段类型也不尽相同,因此就有必要为Grid的列表设计多个方案.在这个自定义系统进行设计的时候,我已经将这部分内容 ...

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

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

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

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

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

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

随机推荐

  1. poi 合并单元格、设置边框

    HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(); //创建一个样式 HSSFCellStyle sty ...

  2. 在WIN7/8下把XP装入VHD (下)

    系统平台:win8.1,安装在C盘 操作目的:在win8.1下装一个VHD  XP. 操作方法: 在http://www.cnblogs.com/mahocon/p/5212914.html里贴了一个 ...

  3. C语言版的16进制与字符串互转函数

    http://www.cnblogs.com/nio-nio/p/3309367.html /* // C prototype : void StrToHex(BYTE *pbDest, BYTE * ...

  4. js框架——angular.js(6)

    1. ng-class 这个指令是用来绑定一个或者多个css代码.它的值一般是一个表达式,也可以是函数什么的,只要返回的确实是一个类的名字就可以—— ng-class="nextPageDi ...

  5. HDU 5722 Jewelry

    矩形面积并. 需要转化一下思路:记录每一个位置的数以及位置. 对数字进行从小到大排序,数字一样的按位置从小到大排. 这样,一样的数就在一起了.连续的相同的x个数就可以构成很多解,这些解对应于二维平面上 ...

  6. 用cas来实现php的单点登陆

    最近项目中需要做单点登录,客户端包含Java.ruby和PHP,java有几个应用程序,php是discuz+supesite+ucenter,配置步骤如下: 1.cas服务端:下载地址:http:/ ...

  7. 关于VC中的错误处理

    include <exception> try {} cache(exception &e) { cout<<e.what()<<endl; }     但 ...

  8. C++头文件#include<bits/stdc++.h>

    一句话的事,直截了当——#include<bits/stdc++.h>包含C++的所有头文件 参考网站(点击):http://www.tuicool.com/articles/m6neUj ...

  9. 第15章 I/O(输入/输出)

    在变量.数组和对象中存储的数据是暂时存在的,程序结束后它们就会丢失.为了能够永久地保存创建的数据,需要将其保存在磁盘文件中,这样就可以在其它程序中使用它们.Java的I/O技术可以将数据保存到文本文件 ...

  10. JS清除dropdownlist绑定的项,并添加新项

    <script type="text/javascript"> /*删除项*/ document.getElementById('KeyList').options.l ...