zoukankan      html  css  js  c++  java
  • 23、手把手教你Extjs5(二十三)模块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;
            }
        }
    });

    现在要加入最后一个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的窗口如下,窗口的高度是自动适应的。

    lljx1le3

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

  • 相关阅读:
    PAT 天梯赛 L2-003. 月饼 【贪心】
    PAT 天梯赛 L2-015. 互评成绩 【排序】
    PAT 天梯赛 L1-046. 整除光棍 【模拟除法】
    PAT 天梯赛 L1-006. 连续因子 【循环】
    PAT 天梯赛 L1-009. N个数求和 【模拟】
    HackerRank
    ZOJ 3961 Let's Chat 【水】
    ZOJ 3960 What Kind of Friends Are You? 【状态标记】
    ZOJ 3959 Problem Preparation 【水】
    ZOJ 3958 Cooking Competition 【水】
  • 原文地址:https://www.cnblogs.com/niejunchan/p/4997026.html
Copyright © 2011-2022 走看看