首页 > 代码库 > 跟我一起学extjs5(24--模块Form的自定义的设计[2])
跟我一起学extjs5(24--模块Form的自定义的设计[2])
跟我一起学extjs5(24--模块Form的自定义的设计[2])
在本节中将要加入各种类型的字段,在加入字段的时候由于可以一行加入多个字段,因此层次结构又多了一层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; } } });
/** * 用于生成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字段等等,我现在的这个讲解只提供一个自定义的思路,有更多想法还要自己去实现。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。