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) == ) {
                        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: ,
        title: "用户权限设置",
        forceFit: true,
        frame: false,
        store: "emDataStore",
        columns: columns,
        plugins: [
                {
                    ptype: "rowediting",
                    clicksToEdit: 
                }
        ],
        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) }
                    });
                }
            }
        ]
    });
});

编辑器验证

参看:自定义验证

编辑器事件

编辑器事件写在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: '操作',
                width: ,
                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>

Javascript - ExtJs - GridPanel组件 - 编辑的更多相关文章

  1. Javascript - ExtJs - GridPanel组件

    GridPanel组件(Ext.grid.GridPanel)logogram:Ext.grid.Panel | xtype:gridpanel 此类派生自Ext.Panel,创建表格需要两个必须的对 ...

  2. Javascript - ExtJs - Window组件

    1.所有组件都可以放入window,此时子组件不需要配置renderTo,只需要将它们作为window的items子项即可. 2.items子项必须先创建,最后创建window,否则子项不会显示. 3 ...

  3. Javascript - ExtJs - TreePanel组件

    TreePanel组件(Ext.tree.TreePanel)logogram:Ext.tree.Panel | xtype:treepanel 树与节点 树面板组件的根是源头,从根上拓展出其它的子节 ...

  4. Javascript - ExtJs - ToolTip组件

    一个浮动的提示信息组件…… Ext,                               //可选 指定箭头的位置     anchor: 'buttom',                  ...

  5. Javascript - ExtJs - XTemplate组件

    XTemplate组件(Ext.XTemplate) 如果有一些重复的html代码需要装入数据,可以考虑使用XTemplate模板组件.XTemplate可以填入数组.对象,支持条件判断.for循环. ...

  6. Javascript - ExtJs - TabPanel组件

    示例 Ext.create('Ext.tab.Panel', {     width: "100%",     renderTo: "tabBox",      ...

  7. Extjs GridPanel用法详解

    Extjs GridPanel 提供了非常强大数据表格功能,在GridPanel可以展示数据列表,可以对数据列表进行选择.编辑等.在之前的Extjs MVC开发模式详解中,我们已经使用到了GridPa ...

  8. Javascript - ExtJs - Ext.form.Panel组件

    FormPanel组件(Ext.form.FormPanel) logogram:Ext.form.Panel | xtype:form Ext.form.Panel.配置 frame }//旗下所有 ...

  9. Javascript - ExtJs - Itemselector

    引入扩展文件 Extjs4.2根目录下: examples \ ux \ css \ images (这是选择按钮的图片资源) examples \ ux \ css \ ItemSelector.c ...

随机推荐

  1. 苹果电脑利用wget总是会出现无法建立 SSL 连接的问题

    在做迁徙学习的过程中,需要下载已经训练好的Inception_v3模型,首先我们为了将下载的模型保存到指定的地方,我们需要利用 wget -P 想要保存的目录 模型的网址,例如 wget -P /Vo ...

  2. JS生成随机数并排序

    JS生成[10,100]之间的十个随机数,并排序 function getRandom(start,end){ var m=end-start+1 return Math.floor(Math.ran ...

  3. javascript(基础)_对数组的遍历方法总结(find, findIndex, forEach,)

    一.前言                                                                                                ...

  4. tcpdump高级过滤

    一:查看帮助选项 tcpdump --help Usage: tcpdump [-aAbdDefhHIJKlLnNOpqStuUvxX#] [ -B size ] [ -c count ] [ -C ...

  5. python模块之os模块

    os模块 用途:调用封装好的方法调用操作系统的功能,处理文件和目录,OS模块不受平台限制. os.name字符串指示你正在使用的平台.比如对于Windows,它是'nt',而对于Linux/Unix用 ...

  6. day10-(rr)

    回顾: http:: 超文本传输协议 请求和响应 servlet: 运行在服务器端的一个java小程序,本质就是一个类 接受请求,处理逻辑,生成动态内容 编写步骤: 1.编写一个类 继承HttpSer ...

  7. HDU5542 BIT优化dp

    http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:求严格递增的长度为M的序列的组数. 当dp的优化方案不那么容易一眼看出来的时候,我们可以考虑先写一个 ...

  8. python对象的多重继承

    一个从多个父类继承过来的子类,可以访问所有父类的功能.并不推荐使用. 多重继承最简单有用的形式是mixin.假设在之前Contact类增加一个功能,允许给self.email发送一封邮件. class ...

  9. Zookeeper+Kafka完全分布式实战部署

    Zookeeper+Kafka完全分布式实战部署 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 其实我之前部署过kafak和zookeeper的完全分布式,集群是可以正常使用没错, ...

  10. es安装的时候遇到的所有的坑

    不允许root用户启动. 解决办法,创建子用户. 在linux下需要注意.es默认不能用root用户启动.我们需要新建一个用户来启动. groupadd  es adduser  es-user    ...