`

Extjs中可编辑表格,树,触发按钮和复选框的结合使用

阅读更多

 

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;
}
注:FastJsonparseArray(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();
}

 
     

 

图示:

 

 

 

 

  • 大小: 1.5 KB
  • 大小: 12.3 KB
  • 大小: 14.7 KB
  • 大小: 23.7 KB
  • 大小: 22.8 KB
  • 大小: 10.7 KB
  • 大小: 12.1 KB
  • 大小: 18.4 KB
  • 大小: 8.2 KB
  • 大小: 3.1 KB
  • 大小: 3 KB
分享到:
评论

相关推荐

    Extjs中文api

    6. **表单(Forms)**: 表单组件用于收集用户输入,支持各种表单字段类型,如文本框、复选框、下拉框等,并且可以方便地验证用户输入。 7. **树形视图(Tree)**: 树形视图用于展示层次结构的数据,可以展开、折叠...

    ExtJs3.0中文API

    - **Form**: 表单组件,包括文本框、复选框、下拉列表等,支持验证和数据提交。 - **Grid**: 数据展示组件,可以显示大量数据,并支持排序、分页、编辑等功能。 - **Tree**: 树形结构组件,用于展示层次化数据。 ...

    ExtJS 实用教程

    6. **Form组件**:ExtJS提供了多种表单控件,如文本框、下拉框、复选框等,以及表单验证机制。通过FormPanel可以方便地创建和管理用户输入。 7. **图表组件**:ExtJS的图表组件能生成各种类型的图表,如柱状图、...

    ExtJS-3.4.0系列目录

    - `Ext.form.CheckboxGroup` 和 `Ext.form.RadioGroup`:用于组合复选框和单选框。 - `Ext.form.field.Trigger`:触发字段,常用于下拉搜索框。 - `Ext.form.field.Spinner`:用于数字的微调。 - `Ext.form....

    ExtjsAPI2文档

    4. **表单组件与表单处理**:ExtJS拥有丰富的表单组件,如文本框、下拉框、复选框、单选按钮等,并支持复杂的数据验证和远程提交。表单API允许开发者轻松地处理用户输入和数据提交。 5. **数据存储**:通过Store...

    Extjs4 api

    6. **Form组件**:包括各种表单元素如文本框、下拉框、复选框等,支持数据验证和表单提交。表单绑定模型,实现数据的双向同步。 7. **Ajax请求**:Ext.Ajax模块提供异步数据请求功能,支持JSONP、XMLHttpRequest等...

    extjs 3.3 API文档与源文件

    ExtJS 3.3提供了丰富的表单组件,如文本框、复选框、下拉列表等,以及用于验证和提交表单的FormPanel。表单组件支持联动、验证和自定义渲染,便于创建复杂的表单界面。 6. **工具提示与弹出框**: 提供了强大的...

    ExtJs组件类的对应表

    4. **`checkitem`** - `Ext.menu.CheckItem`,选项菜单项,具有复选框的菜单项。 5. **`menuitem`** - `Ext.menu.Item`,基本菜单项,用于创建简单的菜单项。 6. **`menuseparator`** - `Ext.menu.Separator`,...

    ExtJS的xtype列表

    - `menucheckitem`: 在菜单中添加复选框功能的菜单项。 - `menuitem`: 菜单的基本项。 - `menuseparator`: 菜单中的分隔线。 - `menutextitem`: 在菜单中显示文本的菜单项。 5. **表单及表单域组件**: - `...

    Extjs xtype集合

    - **描述**: 可编辑的表格组件,允许用户直接在表格中编辑数据。 12. **`propertygrid`:** - **`xtype`**: `propertygrid` - **`Class`**: `Ext.grid.PropertyGrid` - **描述**: 用于展示属性的表格,适用于...

    ExtJs xtype一览

    - **`menucheckitem` (Ext.menu.CheckItem)**: 选项菜单项组件,提供了一个复选框。 - **`menuitem` (Ext.menu.Item)**: 菜单项组件,用于创建菜单中的单个项目。 - **`menuseparator` (Ext.menu.Separator)**: 菜单...

    ext表单设计器,常用表单拖拉实现

    它们支持多种类型的字段,如文本框、复选框、单选按钮、下拉列表等,并且可以进行复杂的布局管理,如表格布局、流式布局和绝对布局。表单设计器通常包括以下关键功能: 1. **字段拖放**:在设计器中,你可以从一个...

    EXT WebUi标签库使用说明

    - **checkBoxGroup**:一组复选框,便于管理多个复选框的选中状态。 - **select**:下拉框,支持编辑和智能填充,提升用户体验。 - **dateEdit**:日期选择器,方便用户输入日期信息。 - **groupBox**:分组容器...

    Ext Js权威指南(.zip.001

    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...

    Ext JS - JavaScript Library

    6. **表单组件**:Ext JS 提供了丰富的表单组件,如文本框、下拉列表、复选框、单选按钮等,以及表单验证和数据提交功能,便于创建用户输入界面。 7. **Ajax和JsonP**:库内内置了Ajax和JsonP支持,方便开发者实现...

    JXstar平台开发手册1.2

    - **在树形控件中显示本级复选框**: 如何在树形控件中显示当前层级的复选框。 - **在Grid工具中添加“时间段、部门选择”的查询栏**: 如何在Grid工具栏中添加时间段和部门选择功能。 ##### 1.5 常见Form扩展脚本 - ...

    Ext组件描述,各个组件含义

    - **功能描述**:Checkbox 是一个复选框控件,用户可以通过勾选来选择或取消选择。 - **主要用途**:适用于需要用户进行多选操作的场景。 **2.18 ComboBox (Ext.form.ComboBox)** - **xtype**: `combo` - **功能...

Global site tag (gtag.js) - Google Analytics