Extjs中可编辑表格,树,触发按钮和复选框的结合使用
1.数据源Store:
/*1.创建Record*/ var costRecord = new Ext.data.Record.create([ {name:"id",type:"int"}, {name:"xmid",type:"int"}, {name:"subject",type:"string"}, {name:"subjectId",type:"string"}, {name:"planCost",type:"string"}, {name:"actualCost",type:"string"} ]); /*2.创建Store*/ var costStore = new Ext.data.Store({ //注意JsonStore和Store的区别 url:"getProjectCost.eva?doType=getProjectCost", reader: new Ext.data.JsonReader({ root:"data" },costRecord) });
2.列ColumnModel:
var selectedCostRow;//定义全局变量,获取点击列表某一行时通过复选框获得的行号。 //复选框 var costSm = new Ext.grid.CheckboxSelectionModel(); /* costSm.handleMouseDown = Ext.emptyFn; */ //触发域 var costTrigger = new Ext.form.TriggerField({ emptyText:"请选择...", allowBlank:false, readOnly:true, onTriggerClick:function(e){ //单击触发按钮触发的事件 selectedCostRow = costSm.getSelected(); costTreeWin.show(); } }); var costCm = new Ext.grid.ColumnModel({ columns:[ costSm, //在列中加上定义的复选框 { header:"编号", dataIndex:"id", width:200, hidden:true },{ header:"项目编号", dataIndex:"xmid", width:200, hidden:true, editor:new Ext.form.TextField({ //此处加上可编辑文本框 id:"costXmid" }) },{ header:"支出内容(经济科目)", dataIndex:"subject", width:200, editor:costTrigger //此处加上触发域 },{ header:"经济科目ID", dataIndex:"subjectId", width:200, hidden:true },{ header:"计划支出数(单位:元)", dataIndex:"planCost", width:200, editor:new Ext.form.TextField({ allowBlank: false }) },{ header:"实际支出数(单位:元)", dataIndex:"actualCost", width:200, editor:new Ext.form.TextField({ allowBlank: false }) } ] });
注意:若加上了costSm.handleMouseDown = Ext.emptyFn; 则点击复选框才能选中,点击行不能选中。
若不加这句话,则点击行即可选中复选框!
3.可编辑表格面板:EditorGridPanel
/*4.创建表格面板*/ var costGrid = new Ext.grid.EditorGridPanel({ cm:costCm, sm:costSm, //表格中也必须加上定义的复选框才行 store:costStore, clicksToEdit:1, //设置点击几次才可以编程 stripeRows: true, //斑马线的表格 loadMask:{msg:'正在加载数据,请稍侯……'}, height:480, width:630, tbar:[ { text:"保存", iconCls:"save", handler:saveCost //点击调用保存方法 },{ text:"增加", iconCls:"add", handler:function(){ var newCost = new costRecord({ //此处创建新的Record id:-1, xmid:Ext.getCmp("costXmid").getValue(), subject:'', subjectId:'', planCost:'', actualCost:'' }); costGrid.stopEditing(); //关闭表格的编辑状态 costStore.add(newCost); //store.insert(0, newCost); //创建的Record插入store的第一行 //store.insert(store.getCount(), newCost); //创建的Record插入store的最后一行 costGrid.startEditing(0, 0); //激活第一行第一列的编辑状态 } },{ text:"删除", iconCls:"remove", handler:removeCost //点击调用删除方法 } ] }); /*创建保存收支明细方法,只保存修改过的信息*/ function saveCost(){ //只提交修改过的记录 var rcds = costStore.getModifiedRecords(); //获取修改过的记录集Records if(rcds&&rcds.length>0){ Ext.Msg.wait("正在保存..."); var rows=new Array(); for(var i=0;i<rcds.length;i++){ var rs = rcds[i]; //获取指定下标的某一行的记录Record var row=new Object(); var fields=rs.data; //获取该行记录的数据Data row = {id:fields.id,xmid:fields.xmid,subjectId:fields["subjectId"],planCost:fields["planCost"],actualCost:fields["actualCost"]}; rows.push(row); //注意此处获取属性方式:obj.id或者obj["id"] } //因为此处obj是data,这些id,name都是data的属性 //如果直接用record,则可以用它在Extjs中定义的get方法:rs.get("id") Ext.Ajax.request({ url: 'updateProjectCost.eva?doType=updateProjectCost', method:'POST', timeout:300000, success: result, failure: function(){Ext.Msg.alert('信息','未成功提交数据!'); }, params:{updateSets :Ext.encode(rows)} //将数组转化为JSON字符串!!! }); function result(response, options){ var result = Ext.util.JSON.decode(response.responseText); if(result.success){ Ext.Msg.hide(); Ext.Msg.show({ title:'成功', msg: '数据保存成功', buttons: Ext.Msg.OK, icon: Ext.MessageBox.INFO }); //保存成功后刷新修改过的脏数据。 costStore.rejectChanges(); costStore.reload(); }else{ Ext.Msg.hide(); Ext.Msg.alert('信息','保存数据未成功!'); } } } } /*创建删除收支信息的方法,删除复选框勾选的记录*/ function removeCost(){ var rcs = costGrid.getSelectionModel().getSelections(); if(!rcs||rcs.length<1){ Ext.Msg.alert("提示","请先选择要删除的行"); return; } else{ Ext.Msg.confirm("确认删除","请确认是否删除选中的项目支出条目?",function(btn){ if(btn == "yes"){//选中"是"的按钮 var ids = new Array(); for (var i = 0; i < rcs.length; i++) { ids.push(rcs[i].get("id")); } //异步发请求 Ext.Ajax.request({ url:"deleteCosts.eva?doType=deleteCosts", method:"POST", params:{costIds:ids.join(",")}, success:function(response,option){ var result = Ext.util.JSON.decode(response.responseText); if (result.success) { Ext.Msg.alert("成功","选中的项目支出条目已成功删除!"); costStore.rejectChanges(); costStore.reload(); } }, failure:function(response,option){ Ext.Msg.alert("失败","删除过程中发生错误!"); } }); } }); } }
注:
Ext中将数组转化为JSON字符串的方式:Ext.encode(array);
数组转json的数据如下:
[ { "id": 1, "xmid": 1, "subject": "餐饮", "subjectId": 1, "planCost": 100, "actualCost": 200 }, { "id": 2, "xmid": 2, "subject": "医疗", "subjectId": 2, "planCost": 300, "actualCost": 500 } ]
Servlet:处理传入的json数据,并保存:
if("updateProjectCost".equals(action)){ ProjectCostDao costDao = new ProjectCostDao(); String sData = request.getParameter("updateSets"); List<ProjectCost> projectCosts = JSON.parseArray(sData, ProjectCost.class);//将Json字符串转化为集合 boolean done = costDao.updateProjectCosts(projectCosts); String str=null; if(done){ str="{success:true}"; }else{ str="{success:false}"; } response.setContentType("text/html;charset=UTF-8"); out=response.getWriter(); out.print(str); out.close(); return; }注:用FastJson的parseArray(jsonStr, T.class)方法可直接将符合设定的类的格式的JSON字符串转化成集合!
Dao:保存数据
/** * 方法一:自己定义主键ID,对于新数据定义ID为-1,再根据ID判断是更新还是插入 */ public boolean updateProjectCosts(List sets){ boolean done = false; if(sets==null||sets.size()==0){ return true; } Session s = null; try{ s = HibernateUtil.getSession(); s.beginTransaction(); for(int i=0;i<sets.size();i++){ ProjectCost cost = (ProjectCost) sets.get(i); int id = cost.getId(); if(id<0){//新增 s.save(cost); }else{ ProjectCost initCost = (ProjectCost) s.get(ProjectCost.class, id); if (initCost != null) { initCost.setXmid(cost.getXmid()); initCost.setCostSubject(cost.getCostSubject()); initCost.setPlanCost(cost.getPlanCost()); initCost.setActualCost(cost.getActualCost()); s.flush(); } } } s.getTransaction().commit(); done = true; }catch(Throwable e) { logger.error(e.toString()); HibernateUtil.endSession(s); }finally{ HibernateUtil.endSession(s); } return done; } /** * 方法二:直接用saveOrUpdate,Hibernate会自动根据主键查询,有则更新,无则插入————更加方便快捷! */ public boolean updateProjectCosts(List<ProjectCost> projectCosts){ boolean done = false; if(projectCosts==null||projectCosts.size()==0){ return true; } Session s = null; try{ s = HibernateUtil.getSession(); s.beginTransaction(); for(int i=0;i<projectCosts.size();i++){ ProjectCost projectCost = projectCosts.get(i); s.saveOrUpdate(projectCost); } s.getTransaction().commit(); done = true; }catch(Throwable e) { HibernateUtil.endSession(s); }finally{ HibernateUtil.endSession(s); } return done; }
自己根据ID判断:
直接用saveOrUpdate:
4.树面板TreePanel:注意查看下面标注的顺序
/*5.创建树形节点下拉选*/ //1.定义根节点 var costRoot = new Ext.tree.AsyncTreeNode({ id:'tree-root', text:"经济科目", expanded:true, //根节点默认展开(注意和TreePanel中的rootVisible:true的联系) draggable:false //根节点不可拖动 }); //2.定义节点数据加载器 var costLoader = new Ext.tree.TreeLoader({ dataUrl:'getTree.base?doType=getPTreeByGrade&onlyValid=1', //此处不是url,和Store的Proxy不同 baseParams :{pid:''}, baseAttrs:{uiProvider:Ext.tree.TreeCheckNodeUI} //必须有该项,不然树节点无法出现选择框 }); //3.定义数据加载前触发方法 costLoader.on("beforeload",function(treeLoader,node){ treeLoader.baseParams.pid = node.id; },this); //4.定义树形面板,用于显示数据 var costTree = new top.Ext.tree.TreePanel({ /**注意top!!!*/ root:costRoot, //根节点 loader:costLoader, //数据加载器 autoScroll:true, animate:false, enableDD:false, //不允许子节点拖动 rootVisible:true, //显示根节点 checkModel:"single", //复选框只能单选,多选为:multiple,级联:cascade onlyLeafCheckable:true, width:250, listeners:{"click":function(node){ if(!node.isLeaf()){ node.toggle(); //点击可展开可收缩 } }} }); //5.创建树节点窗口 var costTreeWin = new top.Ext.Window({ /**注意top!!!*/ title:"经济科目", layout:"fit", closeAction:"hide", modal:true, width:250, height:250, items:costTree, buttons:[ { text:"确定", handler:function(e){ var node = costTree.getChecked(); //获取被选中的树节点 if(!node || node.length < 1){ Ext.Msg.alert("系统提示","请选择经济科目!"); return; } var name = new Array(); var value = new Array(); for (var i = 0; i < node.length; i++) { name.push(node[i].text); value.push(node[i].id); } var data = selectedCostRow.data; //获取选择的行的Record的Data数据对象 data["subjectId"] = value.join(); /*data["subject"]= name.join(); —— —— 此处用这种方式给触发域赋值出错!!!必须用下面的方式!!! */ costTrigger.setValue(name.join()); costTreeWin.hide(); } },{ text:"取消", handler:function(){ costTreeWin.hide(); } } ] });
注意事项:
1.在可编辑表格面板中加触发域TriggerField,则关联的树面板TreePanel和树窗口Window在定义时必须用top置顶!!!否则无法在单元格中显示被选中的数据。
2.通过selectedRow.data获取选中的行所对应的Record的Data对象(注意该Data是Object对象!)
3.通过data["subjectId"] = value.join()方式,给该data对象中的各种属性赋值。(注意改变的实际是Store的值!!)
4.给TriggerField触发域占用的单元格赋值,必须用:costTrigger.setValue(name.join())
此处若还是用data["subject"] = name.join(),则会报错,原因尚未深究。
查询树节点的SQL:
SELECT * FROM (SELECT BM, MC, PID, ISLEAF, LEVEL FROM (SELECT BM, MC, PID, 0 AS ISLEAF FROM BM_CONT WHERE TABLE_BM = 'BM_GRADE' AND YEAR = 2014 UNION SELECT TO_CHAR(ID) AS BM, FILENO AS MC, GID AS PID, 1 AS ISLEAF FROM POLICY) CONNECT BY PRIOR BM = PID START WITH PID IS NULL)
查到的树节点的数据:
(具体数据请查看附件!)
5.窗口Window:
/*6.创建收支明细窗口*/ var costWin = new Ext.Window({ title:"收支明细", frame:"fit", closeAction:"hide", modal:true, items:costGrid });
6.点击显示窗口时传递需要的参数:
function showCostWin(xmid){ Ext.getCmp("costXmid").setValue(xmid); costWin.show(); costStore.baseParams.xmid = xmid; costStore.load(); }
图示:
相关推荐
基于EXTjs 的 动态复选框树 json数据交互
分享一个ExtJs Tree, 完整的带有复选框的树形结构
extjs3.2 3.3 3.4都测试过可以使用,带有复选框的树菜单,选中父节点子节点全部选中,选中子节点父节点选中(以及父节点的父节点等),其余版本不知道能否使用
extjs带复选框的树包括全选 反选 子选父以及 父选子 与adf在jsp页面得应用 包含了工具类以及针对extjs树节点增加、删除、修改的工具方法
实现了从后台读取数据,并进行分页显示,从后台读取treepanel数据,显示,并实现了点击节点复选框的时候,出现父节点和子节点的联动,运行环境是vs2008
extjs4.1下拉复选框完整DEMO,包含了extjs4.1主文件,代码实现了动态加载功能,所以需要配置IIS或者apache。插件文件在ux目录下,请自行参考。
extjs 可编辑的表格树,每个单元格自定义编辑组件,可以自适应列宽,只有源码与例子,运行实例要修改路径,不然图片不能显示,注意etree.jsp的js引入路径 支持Ext2.x以上版本 如运行不了EmailTo : codeme9@gmail....
网上搜索了许久未找到...Extjs4.2 带复选框的下拉树,解决了向下勾选子节点、向上勾选父节点,正选反选获取值等问题,勾选的节点显示displayfield值直接显示在下拉文本框中。需要引用ext-all.js和ext-all-neptune.css
extjs表格、树控件
1、解压,进入extjs4.2.1\examples\form,浏览器打开 hbox-form.html 文件,当我勾选中任意一个多选下拉框,然后再勾选‘ALL’时,‘ALL’却是不被选中的状态,且输入框里没有值 2、下拉列表选择功能的js代码在下面...
使用extjs+ibatis+spring+struts开发的权限系统 数据库mysql 数据库文件在开发文档目录下 动态树形菜单的加载 ,用户角色权限菜单的维护 jar文件删了一些,需要用的自己加包
提问 - Boxy.ask() - 用户定义的选项,选择项传递给回调函数 弹出 - Boxy.alert() - 回调函数总是不被调用 确认 - Boxy.confirm() - 仅当用户选择了“确认”时回调函数会被调用 行业选择器 - Boxy.industry() - 仅当...
今天系统中有处地方需要一个功能点击一个按钮后将树节点前的复选框去掉,变成没有选择的状态。网上搜索了半天,然后自己查查API,终于找到解决办法了,下面把方法贴出来。 在Extjs3.x和4.x版本中的处理方法是不一样...
extjs目录树编辑对目录增删改查学习extjs的工具类
EXTJS实例 EXTJS树,可以编辑的EXTJS,EXTJS3.0
extjs4 框架实现树形结构的下拉框,并支持多选、复选,项目中开发实际用到的,这里提供了前段的js代码,大家有用到的,可以进行参考。
extjs动态生成表格,前台+后台extjs动态生成表格,前台+后台extjs动态生成表格,前台+后台extjs动态生成表格,前台+后台extjs动态生成表格,前台+后台extjs动态生成表格,前台+后台
extjs树型表格组件的使用示例,详细说明可以参见http://blog.csdn.net/snail_spoor/article/details/39698037