• Javascript


    GridPanel组件 - 编辑

    Ext.grid.plugin.Editing

    如果要对表格使用列编辑器控件,则需要完成以下几步

    1.将columns中需要编辑的列设为editor并提供编辑列时所要使用的表单控件。

    2.通过配置gridPanel的plugins指向编辑器实例。

    3.指示gridPanel的选择模式为列或行选择模式。

    列编辑器(Ext.grid.plugin.CellEditing [ ptype: "cellediting" ])

    var columns = [
        { header: '编号', dataIndex: 'id' },
        {
            header: '性别',
            dataIndex: 'name',
            editor: {
                xtype: "combobox",//xtype表示实例化一个组件或控件对象,相当于new Ext.form.combobox(),对象名称全小写。
                allowBlank: false//不允许空值
            }
        },
        {
            header: '描述', dataIndex: 'descn', 
            editor: {
                xtype: "textfield",
                allowBlank: false,//不允许空值
                selectOnFocus: true//点开编辑时自动选中值以便于用户删除。
            }
        }
    ];

    var grid = new Ext.grid.GridPanel({
        renderTo: 'box',
        store: store,
        columns: columns,
        selType: 'cellmodel',//指示为列选择模式
        plugins: [//绑定列编辑器插件
            {
                ptype: "cellediting",//列编辑器插件
                clicksToEdit: 2//点击2次开启编辑
            }
        ]
    }); 

    行编辑器(Ext.grid.plugin.RowEditing [ ptype: "rowediting" ])

    Ext.create("Ext.grid.Panel", {
        //……
        plugins: [//绑定行编辑器插件
            {
                ptype: "rowediting",//行编辑器插件
                clicksToEdit: 2//点击2次开启编辑
            }
        ]
    });

    下拉框编辑器

    数据源为本地数据 

    //配置数据存储器
    Ext.create("Ext.data.ArrayStore", {
        fields: ["key", "value"],//随便设 key是显示的文本 value是文本对应的值
        data: [
            ["重庆", "chongqing"],//重庆对应key 1对应value
            ["长沙", "changsha"],
            ["上海", "shanghai"]]
    });

    //为GridPanel配置columns
    var columns = [
        { header: "编号", dataIndex: "ID" },
        {
            header: "城市",
            dataIndex: "Name",
            editor: {
                xtype: "combobox",
                triggerAction: "all",
                emptyText: "请选择",
                store: datasourceStore,
                mode: "local",
                displayField: "key",
                valueField: "value",
                listeners: {
                    select: function () {
                        Ext.Msg.alert("", this.value);
                    }
                }
            }
        },
    ];

    数据源为服务端数据 

    Ext.define("AdminRole", {
        extend: "Ext.data.Model",
        fields: [
            { name: "Id", type: "int" },
            { name: "Name", type: "string" }
        ]
    })

    Ext.create("Ext.data.Store", {
        storeId: "AdminRoleDataStore",
        autoLoad: true,
        model: "AdminRole",
        proxy: {
            type: "ajax",
            url: "AdminAdminRoleHandler.ashx",
            reader: {
                type: "json",
                root: "ds" //如果Json格式带根,此处要指定根,如这样的json数据:{ "ds" : [ { record1 : "" } , { record2 : "" } ] }
            }
        }
    });

    var columns = [
        {
            header: "角色", dataIndex: "roleName",
            editor: { xtype: "combobox", id: "roleCombo", store: "AdminRoleDataStore", mode: "remote", triggerAction: "all", displayField: "Name", valueField: "Id", editable: false }
        }
    ]

    下拉框选中后显示的是值而非文本的解决办法

    之前有试过在编辑器的列配置renderer,但发现一旦点击列头的排序功能时,所有的下拉框列的值都会被改掉,既然如此就没必要在此处动手脚。我换了一个思路,直接将下拉框列的displayField和ValueField都配置成key,这样选中后显示的就通通是key而非value了,然后我写了一个函数,用于获取GridPanel中所有修改过数据的记录,该函数返回的记录中包含的下拉框数据就是value而非key。如果觉得麻烦,其实简单的办法就是不要在表格上编辑数据,应另外弹出一个窗口,使用表单编辑数据。如果非要使用编辑器,可以考虑如下实现  

    // #region 返回GridPanel中被污染过的脏数据集合 //每行中只要有一个列被修改过就会返回该行的全部数据,未修改过的不会返回。这包含了被选中的下拉框选项的value。有不需要提交的字段可以迭代返回的结果,delete即可   
    function GetDityRec(gridStoreID, cArray) {
        //获取gridPanel中的脏数据
        var drityDatas = Ext.getStore(gridStoreID).getModifiedRecords();
        var submitRecord = [];
        var transcript;

        //遍历每条记录
        drityDatas.forEach(function (gridRecord) {
            Ext.each(cArray, function (obj) {
                //获取下拉框数据存储器
                var comboStore = Ext.getStore(obj.comboStoreID);
                var key = gridRecord.get(obj.gridDisplayField);
                comboStore.findBy(function (comboRecord) {
                    if (comboRecord.get(obj.displayField) == key) {
                        if (cArray.indexOf(obj) == 0) {
                            transcript = gridRecord.data;//首次应拷贝行的副本,此后则直接赋值
                        }
                        transcript[obj.gridDisplayValueField] = parseInt(comboRecord.get(obj.valueField));
                    }
                });
            });
            submitRecord.push(transcript);
        });
        return submitRecord;
    }
    // #endregion
    GetDityRec

    使用GetDityRec的示例

    employee表,除了Id和Name,其余字段分别对应了三张表,在客户端的GridPanel中点击编辑列时,这些列会变成下拉框,通过它们各自的数据存储器去查询对应的表,以combobox显示这些数据。

    Ext.onReady(function () {

        //employee表的数据模型和存储器
        Ext.define("em", {
            extend: "Ext.data.Model",
            fields: [
                { name: "Id", type: "int" },
                { name: "Name", type: "string" },
                { name: "sexId", type: "int" }, 
                { name: "GenderName", type: "string" },
                { name: "favitId", type: "int" },
                { name: "FavitName", type: "string" },
                { name: "jobId", type: "int" },
                { name: "JobName", type: "string" }
            ]
        });

        Ext.create("Ext.data.Store", {
            id: "emDataStore",
            autoLoad: { params: { getEmployeeList: "true" } },
            model: "em",
            proxy: {
                type: "ajax",
                url: "employeeHandler.ashx",
                reader: {
                    type: "json",
                    root: "ds",
                }
            }
        });

        //三个下拉框的数据模型和存储器
        Ext.define("Gender", {
            extend: "Ext.data.Model",
            fields: [
                { name: "Id", type: "int" },
                { name: "GenderName", type: "string" }
            ]
        })

        Ext.create("Ext.data.Store", {
            id: "GenderDataStore",
            model: "Gender",
            autoLoad: true,
            proxy: {
                type: "ajax",
                url: "GenderHandler.ashx",
                extraParams: { getGenderList: "true" },
                reader: {
                    type: "json",
                    root: "ds"
                }
            }
        });

        Ext.define("Favit", {
            extend: "Ext.data.Model",
            fields: [
                { name: "Id", type: "int" },
                { name: "FavitName", type: "string" }
            ]
        })

        Ext.create("Ext.data.Store", {
            storeId: "FavitComboStore",
            autoLoad: true,
            model: "Favit",
            proxy: {
                type: "ajax",
                url: "FavitHandler.ashx",
                extraParams: { getFavitList: "true" },
                reader: {
                    type: "json",
                    root: "ds"
                }
            }
        });

        Ext.define("Job", {
            extend: "Ext.data.Model",
            fields: [
                { name: "Id", type: "int" },
                { name: "JobName", type: "string" }
            ]
        })

        Ext.create("Ext.data.Store", {
            storeId: "JobComboStore",
            autoLoad: true,
            model: "Job",
            proxy: {
                type: "ajax",
                url: "JobHandler.ashx",
                extraParams: { getJobList: "true" },
                reader: {
                    type: "json",
                    root: "ds"
                }
            }
        });

        //注意下面的三个下拉框的displayField和valueField用的都是key而非value
        var columns = [
            { xtype: "rownumberer" },
            { header: "用户名", dataIndex: "Name" },
            {
                header: "性别", dataIndex: "sexId", menuDisabled: true,
                editor: {
                    xtype: "combobox", id: "GenderComboEdit", store: "GenderDataStore", mode: "remote", triggerAction: "all", displayField: "GenderName", valueField: "GenderName", editable: false
                }
            },
            {
                header: "爱好", dataIndex: "favitId", menuDisabled: true,
                editor: {
                    xtype: "combobox", id: "FavitComboEdit", store: "FavitComboStore", mode: "remote", triggerAction: "all", displayField: "FavitName", valueField: "FavitName", editable: false
                }
            },
            {
                header: "职位", dataIndex: "jobId", menuDisabled: true,
                editor: {
                    xtype: "combobox", id: "JobComboEdit", store: "JobComboStore", mode: "remote", triggerAction: "all", displayField: "JobName", valueField: "JobName", editable: false
                }
            }
        ]

        Ext.create("Ext.grid.Panel", {
            id: "gridPanel",
            renderTo: "dataTable",
            width: 300,
            title: "用户权限设置",
            forceFit: true,
            frame: false,
            store: "emDataStore",
            columns: columns,
            plugins: [
                    {
                        ptype: "rowediting",
                        clicksToEdit: 2
                    }
            ],
            buttons: [
                {
                    text: "确定", handler: function () {
                        var c = [
                                //{ displayField: "下拉框的key字段", valueField: "下拉框的value字段", gridDisplayField: "表格对应的下拉框列的key字段", gridDisplayValueField: "表格对应的下拉框列的value字段", comboStoreID: "下拉框存储器" },
                                { displayField: "GenderName", valueField: "Id", gridDisplayField: "GenderName", gridDisplayValueField: "sexId", comboStoreID: "GenderDataStore" }, 
                                { displayField: "FavitName", valueField: "Id",gridDisplayField: "FavitName", gridDisplayValueField: "favitId", comboStoreID: "FavitComboStore" },
                                { displayField: "JobName", valueField: "Id",  gridDisplayField: "JobName", gridDisplayValueField: "jobId", comboStoreID: "JobComboStore" }
                        ];
                        var dityRecords = GetDityRec("emDataStore", c);//返回的是一个数组,存储表格的被修改过的每条记录 [ {  } , {  } ]
                        //测试:dityRecords["字段名"] 或 alert(Ext.encode(dityRecords));
                        //删除不需要的字段:Ext.each ( dityRecords.function ( record ) { delete record.propertyName } ); 
                        Ext.Ajax.request({
                            //……
                            params: { data: Ext.encode(dityRecords) }
                        });
                    }
                }
            ]
        });
    });
    View Code

    sss

    编辑器验证

    参看:自定义验证

    编辑器事件

    编辑器事件写在cellediting、rowediting或类似gridPanel的容器中。在事件中return false可禁止editor的开启。 

    1.列编辑器事件

    /*-----以下事件只能写在类似grid的容器组件中*/
    beforeedit:fn(editor, context)
    //在单元格被编辑前触发事件
    //editor:Ext.grid.plugin.CellEditing对象
    //context:上下文对象,具有以下属性
    //context.grid - 当前gird
    //context.record - 当前被编辑的行,一个Ext.data.Model实例
    //context.field - 要编辑的字段名称
    //context.value - 当前值.
    //context.row - grid的行序号
    //context.column - gird上定义的要编辑的Column.
    //context.rowIdx - 正在编辑的行索引
    //context.colIdx - 正在编辑的列索引,隐藏的行号是列索引0,如果有复选框,则复选框的列索引是1,然后才是其它列的索引
    //context.cancel - 设置为true或者处理函数返回false取消编辑    
    //示例:在gridPanel中注册监听
    listeners: {
        beforeedit: function (editor, e) { e.value = (e.value ==( "此处输入权限名" || "此处输入备注") ? "" : e.value); }
    }
     
    canceledit:fn(editor, context)
    //当编辑单元格但并未做任何更改时触发事件
    //参数与beforeedit一样,但多了以下两个属性
    //context.view - 这个grid的视图
    //context.store - 当前grid的store
        
     
    edit:fn(editor, context)
    //编辑后触发事件
    //参数与canceledit一样,但多了以下两个属性
    //context.originalValues - 字段编辑前该行的原始值
    //context.newValues - 要设置的新值
        
     
    validateedit:fn(editor, context)
    //编辑完成之前且脏数据还未显示在单元格且脏数据正在被验证时触发
    //参数包括了上面3个事件的所有参数

    2.行编辑器事件

    beforeedit:fn(editor, context)
    //在单元格被编辑前触发事件
    //editor:Ext.grid.plugin.CellEditing对象
    //context:上下文对象,具有以下属性
    //context.grid - 当前gird
    //context.record - 当前被编辑的行,一个Ext.data.Model实例
    //context.field - 要编辑的字段名称
    //context.value - 当前值.
    //context.row - grid的行序号
    //context.column - gird上定义的要编辑的Column.
    //context.rowIdx - 正在编辑的行索引
    //context.colIdx - 正在编辑的列索引,隐藏的行号是列索引0,如果有复选框,则复选框的列索引是1,然后才是其它列的索引
    //context.cancel - 设置为true或者处理函数返回false取消编辑.
     
     
    canceledit:fn(editor, context)
    //当编辑单元格但并未做任何更改时触发事件
    //参数与beforeedit一样,但多了以下两个属性
    //context.view - 这个grid的视图
    //context.store - 当前grid的store
     
     
    edit:fn(editor, context)
    //编辑后触发事件
    //参数与canceledit一样,但多了以下两个属性
    //context.originalValues - 字段编辑前该行的原始值
    //context.newValues - 要设置的新值
     
     
    validateedit:fn(editor, context.)
    //编辑完成之前且脏数据还未显示在单元格且脏数据正在被验证时触发
    //参数包括了上面3个事件的所有参数

    更新数据

    编辑完成后要提交服务端处理。 

    Ext.get("btn").on("click",
        function () {
            //遍历store.getModifiedRecords,获得每条记录的data,用简洁数据进行提交。                    
            var dirtyRecords = store.getModifiedRecords();

            var Array = [];
            Ext.each(dirtyRecords, function (item) {
                Array.push(item.data); //遍历以下,取出data用于提交,如果直接用dataModel提交则有可能会出错,因为dataModel有很多无用属性会一并提交到服务端。
            });
            var JsonData = Ext.encode(Array);

            Ext.Ajax.request({
                method: 'POST',
                url: 'updateData.ashx',
                params: { data: JsonData },
                success: function (response) {
                    Ext.Msg.alert('信息', response.responseText, function () {
                        store.reload();
                    });
                },
                failure: function () {
                    Ext.Msg.alert("错误", "与后台联系的时候出现了问题");
                }
            });
        }
    )

    生成特殊对象操作列 

    var columns = [
                { header: "编号", dataIndex: "ID" },
                { header: "姓名", dataIndex: "Name" },
                //特殊列
                {
                    xtype: 'actioncolumn',
                    text: '操作',
                    width: 70,
                    items: [
                        { tooltip: "删除", icon: 'Image/del.ico', handler: function (view, rowIndex, colIndex, node, e, record, rowEl) { alert(record.get("UserId")); } },
                        { tooltip: "编辑", icon: 'Image/edit.ico', handler: function (view, rowIndex, colIndex, node, e, record, rowEl) { alert(record.get("UserId")); } }
                    ]
                }
    ];

    动态控制特殊操作列的按钮的显示 

    {
        xtype: "actioncolumn", text: "操作", align: "center",                 
        items: [
            {
                tooltip: "编辑", icon: "../Image/edit_16px.ico",
                getClass: function (v, metadata, record, rowIndex) {
                    //在服务端写入客户端的权限变量ArticleColumnSetting中查询用户对当前文章是否具有编辑的权限,没有则隐藏按钮
                    if (ArticleColumnSetting.indexOf(record.get("coID") + "_edit") == -1 && ArticleColumnSetting != "all") {
                        return 'x-hidden'
                    }
                }
            },                        
            {
                tooltip: "删除", icon: "../Image/Delete.ico", 
                getClass: function (v, metadata, record, rowIndex) {
                    //在服务端写入客户端的权限变量ArticleColumnSetting中查询用户对当前文章是否具有删除的权限,没有则隐藏按钮
                    if (ArticleColumnSetting.indexOf(record.get("coID") + "_del") == -1 && ArticleColumnSetting!="all") {
                        return 'x-hidden'
                    }
                }                           
            }
        ]
    }

     

    Javascript - 学习总目录

    <script type="text/javascript">
            var columns = [
                { header: "编号", dataIndex: "ID" },
                { header: "姓名", dataIndex: "Name" },
                //特殊列
                {
                    xtype: 'actioncolumn',
                    text: '操作',
                    70,
                    items: [
                        { tooltip: "删除", icon: 'Image/del.ico', handler: function (view, rowIndex, colIndex, node, e, record, rowEl) { alert() } },
                        { tooltip: "编辑", icon: 'Image/edit.ico', handler: function (view, rowIndex, colIndex, node, e, record, rowEl) { alert() } }
                    ]
                }
            ];
        </script>
  • 相关阅读:
    剑指offer-用两个栈实现队列
    Java数组判空的正确打开方式
    浏览器输入URL后后的过程
    HTTP状态码
    HTTP和HTTPS
    北京好未来公司linux面试题
    三剑客 -- sed
    三剑客 -- grep
    shell脚本
    自动化 -- expect
  • 原文地址:https://www.cnblogs.com/myrocknroll/p/7100834.html
Copyright © 2020-2023  润新知