Mocoolka 代码讲解 屏幕生成器之FORM生成

支持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);
        }
    }
});

你可能感兴趣的:(form)