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(); }
图示:
相关推荐
6. **表单(Forms)**: 表单组件用于收集用户输入,支持各种表单字段类型,如文本框、复选框、下拉框等,并且可以方便地验证用户输入。 7. **树形视图(Tree)**: 树形视图用于展示层次结构的数据,可以展开、折叠...
- **Form**: 表单组件,包括文本框、复选框、下拉列表等,支持验证和数据提交。 - **Grid**: 数据展示组件,可以显示大量数据,并支持排序、分页、编辑等功能。 - **Tree**: 树形结构组件,用于展示层次化数据。 ...
6. **Form组件**:ExtJS提供了多种表单控件,如文本框、下拉框、复选框等,以及表单验证机制。通过FormPanel可以方便地创建和管理用户输入。 7. **图表组件**:ExtJS的图表组件能生成各种类型的图表,如柱状图、...
- `Ext.form.CheckboxGroup` 和 `Ext.form.RadioGroup`:用于组合复选框和单选框。 - `Ext.form.field.Trigger`:触发字段,常用于下拉搜索框。 - `Ext.form.field.Spinner`:用于数字的微调。 - `Ext.form....
4. **表单组件与表单处理**:ExtJS拥有丰富的表单组件,如文本框、下拉框、复选框、单选按钮等,并支持复杂的数据验证和远程提交。表单API允许开发者轻松地处理用户输入和数据提交。 5. **数据存储**:通过Store...
6. **Form组件**:包括各种表单元素如文本框、下拉框、复选框等,支持数据验证和表单提交。表单绑定模型,实现数据的双向同步。 7. **Ajax请求**:Ext.Ajax模块提供异步数据请求功能,支持JSONP、XMLHttpRequest等...
ExtJS 3.3提供了丰富的表单组件,如文本框、复选框、下拉列表等,以及用于验证和提交表单的FormPanel。表单组件支持联动、验证和自定义渲染,便于创建复杂的表单界面。 6. **工具提示与弹出框**: 提供了强大的...
4. **`checkitem`** - `Ext.menu.CheckItem`,选项菜单项,具有复选框的菜单项。 5. **`menuitem`** - `Ext.menu.Item`,基本菜单项,用于创建简单的菜单项。 6. **`menuseparator`** - `Ext.menu.Separator`,...
- `menucheckitem`: 在菜单中添加复选框功能的菜单项。 - `menuitem`: 菜单的基本项。 - `menuseparator`: 菜单中的分隔线。 - `menutextitem`: 在菜单中显示文本的菜单项。 5. **表单及表单域组件**: - `...
- **描述**: 可编辑的表格组件,允许用户直接在表格中编辑数据。 12. **`propertygrid`:** - **`xtype`**: `propertygrid` - **`Class`**: `Ext.grid.PropertyGrid` - **描述**: 用于展示属性的表格,适用于...
- **`menucheckitem` (Ext.menu.CheckItem)**: 选项菜单项组件,提供了一个复选框。 - **`menuitem` (Ext.menu.Item)**: 菜单项组件,用于创建菜单中的单个项目。 - **`menuseparator` (Ext.menu.Separator)**: 菜单...
它们支持多种类型的字段,如文本框、复选框、单选按钮、下拉列表等,并且可以进行复杂的布局管理,如表格布局、流式布局和绝对布局。表单设计器通常包括以下关键功能: 1. **字段拖放**:在设计器中,你可以从一个...
- **checkBoxGroup**:一组复选框,便于管理多个复选框的选中状态。 - **select**:下拉框,支持编辑和智能填充,提升用户体验。 - **dateEdit**:日期选择器,方便用户输入日期信息。 - **groupBox**:分组容器...
1.2.4 在javascript中使用json / 4 1.2.5 在.net中使用json / 8 1.2.6 在java中使用json / 12 1.2.7 更多有关json的信息 / 15 1.3 ext js 4概述 / 15 1.4 ext js的开发工具的获取、安装与配置介绍 / 18 1.4.1...
6. **表单组件**:Ext JS 提供了丰富的表单组件,如文本框、下拉列表、复选框、单选按钮等,以及表单验证和数据提交功能,便于创建用户输入界面。 7. **Ajax和JsonP**:库内内置了Ajax和JsonP支持,方便开发者实现...
- **在树形控件中显示本级复选框**: 如何在树形控件中显示当前层级的复选框。 - **在Grid工具中添加“时间段、部门选择”的查询栏**: 如何在Grid工具栏中添加时间段和部门选择功能。 ##### 1.5 常见Form扩展脚本 - ...
- **功能描述**:Checkbox 是一个复选框控件,用户可以通过勾选来选择或取消选择。 - **主要用途**:适用于需要用户进行多选操作的场景。 **2.18 ComboBox (Ext.form.ComboBox)** - **xtype**: `combo` - **功能...