`
kangsoft
  • 浏览: 70497 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ExtJs通用筛选查询控件

阅读更多

在ExtJs项目开发过程中少不了筛选查询功能,而对于这部分功能又基本是大同小异,无非就是对相应条件数据进行筛选查看了,所以我们针对这部分专门去实现了一个控件,用于对所有的数据列表进行查询的通用筛选!

 

先看下示例图:



 

控件核心代码如下:

 

这部分代码比较多,可能再打开浏览器的时候看不到,请大家在附件中下载即可。

 

function createFilter(store,moduleCode,callback)
{
	Ext.form.Field.prototype.msgTarget = "side";
////////////////////变量、常量区////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/**
	 * 当前筛选条件节点
	 * @type  TreeNode
	 */
	var currentFilter={attributes:{}};
	var allOperator={EQ:"0",NE:"1",LIKE:"2",NLIKE:"3",GT:"4",LT:"5",GE:"6",LE:"7",NULL:"8",NOTNULL:"9",ASC:"10",DESC:"11"};
	
	/**
	 * 数字操作运算符集合
	 * @type Array
	 */
	var numericOp = datetimeOp = [[allOperator.EQ, "等于"], [allOperator.NE, "不等于"], [allOperator.GT, "大于"]
					, [allOperator.LT, "小于"], [allOperator.GE, "大于等于"],[allOperator.LE, "小于等于"],[allOperator.NULL, "空白"], [allOperator.NOTNULL, "非空白"]];
	/**
	 * 所有的运算符
	 * @type  Array
	 */
	var allOp = [[allOperator.EQ, "等于"], [allOperator.NE, "不等于"],[allOperator.LIKE, "包含字符"], [allOperator.NLIKE, "不包含字符"], [allOperator.GT, "大于"]
					, [allOperator.LT, "小于"], [allOperator.GE, "大于等于"],[allOperator.LE, "小于等于"],[allOperator.NULL, "空白"], [allOperator.NOTNULL, "非空白"], [allOperator.ASC, "升序"], [allOperator.DESC, "降序"]];
	/**
	 * 字符操作运算符
	 * @type Array
	 */
	var stringOp = [[allOperator.EQ, "等于"], [allOperator.NE, "不等于"],[allOperator.LIKE, "包含字符"], [allOperator.NLIKE, "不包含字符"],[allOperator.NULL, "空白"], [allOperator.NOTNULL, "非空白"]];
	/**
	 * 自定义,下拉框,boolean操作运算符
	 * @type 
	 */
	var lookupOp = booleanOp = [[allOperator.EQ, "等于"], [allOperator.NE, "不等于"], [allOperator.NULL, "空白"], [allOperator.NOTNULL, "非空白"]];
	/**
	 * 最后一行下标
	 * @type Number
	 */
	var lineIndex = 0;// 新增行下标
	/**
	 * 当前编辑行
	 * @type  int
	 */
	var currentIndex=0;// 当前编辑行号
	/**
	 * 左边树面板折叠状态,默认为打开
	 * @type Boolean
	 */
	var treeColFlag=false;
	/**
	 * 第一行下标,默认为0
	 */
	var firstIndex=0;
	/**
	 * 存放排序字段的下标, 避免重复
	 */
	var sortInfo={};
	/**
	 * 筛选结果数据源
	 */
	var filterStore = new Ext.data.Store({//模块列数据源
		id:moduleCode+"_filterStore",
		proxy : new Ext.data.HttpProxy({
					url : "filterAction!getFilterInfo.action"
				}),
		reader : new Ext.data.JsonReader({
					root : "root",
					totalProperty : "total",
					fields : ["fieldName", "fieldId", "fieldLabel", "operator",
								"setValue", "inputType", "fieldType", "inputSql",
								"method", "relation", "rightBr", "leftBr", "sort",
								"displayValue", "delFlag", "idRender","userQueryId","custom"]
				})
	});
	
////////////////////初始化方法区////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//初始化store,如果不是公用Grid 来的,要把fieldType转成相对应的数字
	if(store.getCount()>0)
		store.each(function(rec){
			switch(rec.get("fieldType"))
			{
				case "string":rec.set("fieldType",1);break;
				case "int":rec.set("fieldType",2);break;
				case "float":rec.set("fieldType",3);break;
				case "boolean":rec.set("fieldType",4);break;
				case "date":rec.set("fieldType",5);break;
				case "gender":rec.set("fieldType",6);break;
			}
		})
	else
		store.load();
	
	/**
	 * 文本输入框
	 * @param {int} index 行索引
	 */
	var objGridTextEditor = function(index) {
		return new Ext.form.TextField({
					id : moduleCode+"_setValue" + index,
					emptyText : "请输入..."
				});
	}
	
	/**
	 * 整型输入框
	 * @param {int} index 行索引
	 */
	var objGridIntegerEditor = function(index) {
		return new Ext.form.NumberField({
					id : moduleCode+"_setValue" + index,
					allowNegative : false,
					allowDecimals : false,
					emptyText : "请输入整数..."
				});
	}
	
	/**
	 * 浮点型输入框
	 * @param {int} index 行索引
	 */
	var objGridFloatEditor = function(index) {
		return new Ext.form.NumberField({
					id : moduleCode+"_setValue" + index,
					allowNegative : false,
					emptyText : "请输入数字..."
				});
	}
	/**
	 * boolean选择器
	 * @param {int} index 行索引
	 */
	var objGridBooleanEditor = function(index) {
		return new Ext.form.ComboBox({
					store : [["1", "是"], ["0", "否"]],
					mode : "local",
					triggerAction : "all",
					id : moduleCode+"_setValue" + index,
					editable : false,
					emptyText : "请选择..."
				});
	}
	/**
	 * 性别选择器
	 * @param {int} index 行索引
	 */
	var objGridGenderEditor = function(index) {
		return new Ext.form.ComboBox({
					store : [[1, "男"], [0, "女"]],
					mode : "local",
					id : moduleCode+"_setValue" + index,
					triggerAction : "all",
					editable : false,
					emptyText : "请选择..."
				});
	}
////////////////////公用方法区////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/**
	 * 从store中根据prop的propValue取field值
	 * @param {Ext.data.Store} store 
	 * @param {String} prop 字段
	 * @param {String} propValue 字段值
	 * @param {String} field 结果字段
	 * @return {Object}
	 */
	function findRecordValue(store, prop, propValue, field) {
		var record;
		if (store.getCount() > 0) {
			var _i=0;
			store.each(function(r) {
						if (r.data[prop] == propValue) {
							record = r.data[field];
							if(field=="refData")
								record=store.reader.jsonData[_i].refData;
							return false;
						}
						_i++;
					});
		}
		return record;
	}
	
	/**
	 * 删除当前行
	 */
	var deleteLine = function() {
		panel.remove(moduleCode+"_line"+currentIndex);
		var record = filterStore.getAt(currentIndex);
		var fieldName=record.data.fieldName;
		if(sortInfo[fieldName]+1==currentIndex+1)
			sortInfo[fieldName]=null;
		if(win.customFilter[fieldName]+1==currentIndex+1)
			win.customFilter[fieldName]=null;
		record.set("delFlag", "1");
	}
	
	/**
	 * 删除所有行
	 */
	function delAllLine()
	{
		var count=lineIndex||0;
		for(var j=0;j<=count;j++)
		{
			currentIndex=j;
			deleteLine();
		}
		if(!currentFilter.id){
			filterStore.removeAll();
			lineIndex=0;
		}
		currentIndex=null;
	}
	/**
	 * 根据左边树是否折叠取输入框宽度值
	 * @return {int}
	 */
	function getValueWidth()
	{
		return treeColFlag?197:162;
	}
	/**
	 * 根据左边树是否折叠改变值输入框宽度
	 */
	function changeValueWidth()// 改变值的宽度
	{
		for(var i=0;i<=lineIndex;i++)
		{
			var setv=Ext.getCmp(moduleCode+"_setValue"+i);
			if(!setv)
				continue;
			setv.setWidth(getValueWidth());
		}
	}
	/**
	 * 检查条件是否合法
	 * @return {Boolean}
	 */
	var checkFilter = function() {
		var n = filterStore.getCount();
		var leftPLen = 0;
		var rightPLen = 0;
		for (var i = 0; i < n; i++) {
			var record = filterStore.getAt(i);
			if (record.get("delFlag"))
				continue;
			var leftBr = record.get("leftBr");
			var rightBr = record.get("rightBr");
			leftPLen += leftBr ? leftBr.length : 0;
			rightPLen += rightBr ? rightBr.length : 0;
		}
		if (leftPLen != rightPLen) {
			Ext.Msg.alert("错误", "左括号与右括号数量不匹配,请检查。");
			return false;
		}
		return true;
	}
	/**
	 * 取筛选条件
	 * @return {Array} [修改过的,删除的(只记录有id的)]
	 */
	function getData()
	{
		var removed=[];
		var modified=[];
		filterStore.each(function(record)
		{
			if(!record.get("fieldName"))
				return;
			var operator=record.get("operator");
			var sortFlag=findRecordValue(store, "fieldName", record
							.get("fieldName"), "sort");
			if(sortFlag!=true&&(operator == allOperator.ASC || operator == allOperator.DESC))
				return;
			var dataType = findRecordValue(store, "fieldName", record
							.get("fieldName"), "fieldType");
			var _setValue=record.get("setValue");
			_setValue=_setValue+""=="0"?"0":_setValue;
			if (operator != allOperator.NULL && operator != allOperator.NOTNULL && operator != allOperator.ASC && operator != allOperator.DESC
					&& _setValue== "" && dataType != "6"
					&& dataType != "4")
					return;
			if(record.get("delFlag"))
			{
				if(!record.get("fieldId"))
					return;
				removed.push(Ext.encode(record.data));
			}else
				modified.push(Ext.encode(record.data));
		})
		return [modified,removed];
	}
	/**
	 * 点确认按钮触发事件
	 */
	function okQuery(){
		var respText=Ext.Ajax.request({
			sync:true,
			url:"query!putFilterInSession.action",
			params:{
				modified:getData()[0],
				moduleCode:moduleCode
			}
		});
		var result=Ext.util.JSON.decode(respText.conn.responseText);
		return result;
   }
   function addLineFromRecord(i,rec){
   		var _has=Ext.getCmp(moduleCode+"_fieldName"+i);
   		if(!_has){
			panel.add(getLine(i,true));
			panel.doLayout();
   		}
		Ext.getCmp(moduleCode+"_fieldName"+i).setValue(rec.get("fieldName"));
		if(!_has)
			Ext.getCmp(moduleCode+"_fieldName"+i).fireEvent("change",{value:rec.get("fieldName")});
		var operator=Ext.getCmp(moduleCode+"_operator"+i);
		if(operator==allOperator.ASC||operator==allOperator.DESC)//如果操作符为排序,存入对象
			sortInfo[rec.get('fieldName')]=i;
		var value=Ext.getCmp(moduleCode+"_setValue"+i);
		operator.setValue(rec.get("operator"));
		Ext.getCmp(moduleCode+"_relation"+i).setValue(rec.get("relation"));
		Ext.getCmp(moduleCode+"_operator"+i).fireEvent("change",{value:rec.get("operator")});
		Ext.getCmp(moduleCode+"_rightBr"+i).setValue(rec.get("rightBr"));
		Ext.getCmp(moduleCode+"_leftBr"+i).setValue(rec.get("leftBr"));
		var dataType=findRecordValue(store,"fieldName",rec.get("fieldName"),"fieldType");
		value.setValue(dataType==5?StringToDate(rec.get("setValue")):rec.get("setValue"));
		if(value.store){
			if(value.store.getCount()==0)	
				value.store.reload({callback:function(){
					value.setValue(value.getValue());
				}})
		}
		lineIndex=_has?lineIndex:i;
   }
/**
 * 条件store加载完成后事件,生成筛选框
 */
	function afterFilterStoreLoad()
	{
		var i=0;
		if(filterStore.getCount()>0)
		{
			filterStore.each(function(rec){
				addLineFromRecord(i,rec);
				i=i+1;
			})
			lineIndex=i-1;
		}else
		{
			panel.add(getLine(0));
			panel.doLayout();
		}
	}
	/**
	 * 初始化条件,取当前session中的条件
	 */
	function initFilter(){
		Ext.Ajax.request({
			url : "query!getFilterFromSession.action",
			params:{moduleCode:moduleCode},
			success:function(resp,action){
				var result=Ext.util.JSON.decode(resp.responseText);
				if(result.success){
					delAllLine();
					filterStore.loadData(result,true);
					filterStore.each(function(rec){
						if(rec.data.custom)
							win.customFilter[rec.data.fieldName]=rec.data.sort;
					})
				   filterStore.commitChanges();
					if(store.getCount()==0)
						store.load({callback:function(){afterFilterStoreLoad()}})
					else
						afterFilterStoreLoad();
				}
			}
		})
	}
	/**
	 * 树节点单击后事件
	 */
	function afterTreeClick()
	{
		delAllLine();
		filterStore.reload({params:{"head.id":currentFilter.id},callback:function(){
			afterFilterStoreLoad();
		}});
	}
/**
 * 保存筛选条件
 */
function saveFilter(data)
{
	if(!checkFilter())
			return;
		Ext.Ajax.request({
			url:"filterAction!doSaveFilter.action",
			params:{
				"head.id":currentFilter.id,
				"head.name":currentFilter.text,
				"head.moduleId":currentFilter.attributes.moduleId,
				"head.empId":currentFilter.attributes.empId,
				"head.orgId":currentFilter.attributes.orgId,
				moduleCode:moduleCode,
				modified:data[0],
				removed:data[1]
			},
			success:function(resp, opt) {
				var text = Ext.util.JSON
						.decode(resp.responseText);
				if (text.success){
						filterStore.commitChanges();
						currentFilter.id=text.id;
						filterTree.getRootNode().reload();
					}
			}
		})
}


//////////////////控件区///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * 根据字段名获取编辑器和操作符集合
	 * @param {} fieldName 字段名
	 * @return {}
	 */
	var getChange=function(fieldName,index){
		var _flag=Ext.isNumber(index);
		var _store;
		var _valueStore;
		var dataType;
		var editorType= findRecordValue(store, "fieldName", fieldName, "inputType")
		var idRender= findRecordValue(store, "fieldName", fieldName, "idRender")
		var label=findRecordValue(store, "fieldName", fieldName, "fieldLabel");
		if(editorType)
		{
			if(editorType=="1"&&idRender)
				dataType="text";
			else if(editorType=="4")
				dataType="reference";
			else if(editorType!="1")
				dataType="combo";
		}
		var type=findRecordValue(store, "fieldName", fieldName, "fieldType");
		
		if(!dataType){
			if(!type)
			{
				alert(label+":"+fieldName+"列不能没有‘类型’并且也没有‘输入类型’");
				throw new Error("无效列:"+fieldName);
			}
			switch (type.toString()) {
					case "6" :
						dataType="gender";
						break; 
					case "5" :
						dataType="date";
						break; 
					case "4" :
						dataType="boolean";
						break; 
					case "2" :
						dataType="int";
						break; 
					case "3" :
						dataType="float";
						break;
					default:
						dataType = "text";
						break;
				}
			}
			switch (dataType) {
				case "text" :
					_store = stringOp;
					if(_flag)
						_valueStore = objGridTextEditor(index);
					break;
				case "date" :
					_store = datetimeOp;
					if(_flag)
						_valueStore = new Ext.form.DateField({
									emptyText:"请选择日期...",
									id : moduleCode+"_setValue" + index,
									format:findRecordValue(store, "fieldName", fieldName,"format")||"Y-m-d",
									dateFlag:true
								});
					break;
				case "gender" :
					_store = lookupOp;
					if(_flag)
						_valueStore = objGridGenderEditor(index);
					break;
				case "boolean" :
					_store = booleanOp;
					if(_flag)
						_valueStore = objGridBooleanEditor(index);
					break;
				case "int" :
					_store = numericOp;
					if(_flag)
						_valueStore = objGridIntegerEditor(index);
					break;
				case "float" :
					_store = numericOp;
					if(_flag)
						_valueStore = objGridFloatEditor(index);
					break;
				case "combo" :
					_store = lookupOp;
					if(_flag){
						_valueStore = new Ext.form.ComboBox({
								store : findRecordValue(store, "fieldName", fieldName,"store")||new Ext.data.Store({
										baseParams : {
											type : editorType,
											data : findRecordValue(store, "fieldName", fieldName,
													(editorType=="2")?"inputSql":"method")
										},
										proxy : new Ext.data.HttpProxy({
													url : "querySet!getFieldInputValues.action"
												}),
										reader : new Ext.data.JsonReader({
													root : "root"
												}, [{name:"fieldName",mapping:"value"}, {name:"fieldLabel",mapping:"text"}])
								}),
								mode : "local",
								triggerAction : "all",
								id : moduleCode+"_setValue" + index,
								editable : false,
								valueField : findRecordValue(store, "fieldName", fieldName,"disValue")||"fieldName",
								displayField : findRecordValue(store, "fieldName", fieldName,"disText")||"fieldLabel",
								emptyText : "请选择..."
							});
						if(_valueStore.store.getCount()==0)
							_valueStore.store.load();
					}
					break;
				case "reference" :
					_store = lookupOp;
					if(_flag){
						var _refData=findRecordValue(store, "fieldName", fieldName,"refData");
						_valueStore = new Ext.form.ReferenceField({
								refData : _refData,
								id : moduleCode+"_setValue" + index,
								editable : false,
								emptyText : "请选择...",
								multiple:_refData.multiple||false
							});
					}
					break;
			}
		var sort=findRecordValue(store, "fieldName", fieldName, "sort")&&(!_flag||(sortInfo[fieldName]+""!="0")&&!sortInfo[fieldName]);
		_store=_store.slice(0,_store.length);
		if(sort==true)
			_store.push(allOp[10],allOp[11]);
		return {store:_store,valueStore:_valueStore,dataType:dataType,type:type,inputType:editorType};
	}
	/**
	 * 新增一行条件
	 * @param {int} index 下标
	 * @param {Boolean} edit 如果手动新增不传或传false,自动新增为true
	 */
	var getLine = function(index,edit) {
		/**
		 * 操作符改变事件
		 */
		var operChange = function(ctl, nv, ov) {
			nv=nv||ctl.value;
			Ext.getCmp(moduleCode+"_setValue" + index).setDisabled(false);
			if (nv == allOperator.NULL || nv == allOperator.NOTNULL || nv == allOperator.ASC || nv == allOperator.DESC){
				Ext.getCmp(moduleCode+"_setValue" + index).setDisabled(true);
			}
			var _sort=nv==allOperator.ASC||nv==allOperator.DESC;
			var _reValue=Ext.getCmp(moduleCode+"_relation" + index).getValue();
			var _rec=filterStore.getAt(index);
			var hasSort=true;
			this.store.each(function(_r){
				if(_r.data.value==allOperator.ASC||_r.data.value==allOperator.DESC)
					return hasSort=false;
			})
			if(_sort){
				var _cfieldName=_rec.get("fieldName");
				if(!hasSort)
					sortInfo[_cfieldName]=index;
				Ext.getCmp(moduleCode+"_relation" + index).setValue("");
				Ext.getCmp(moduleCode+"_leftBr" + index).setValue("");
				Ext.getCmp(moduleCode+"_rightBr" + index).setValue("");
				valueChange('relation', "");
				valueChange('leftBr', "");
				valueChange('rightBr', "");
			}else{
				if(!hasSort)
					sortInfo[_cfieldName]=null;
				Ext.getCmp(moduleCode+"_relation" + index).setValue(_reValue||((index==0)?"":"and"));
				valueChange('relation', _reValue||((index==0)?"":"and"));
			}
			
			Ext.getCmp(moduleCode+"_relation" + index).setDisabled(_sort||(index==0));
			Ext.getCmp(moduleCode+"_leftBr" + index).setDisabled(_sort);
			Ext.getCmp(moduleCode+"_rightBr" + index).setDisabled(_sort);
			valueChange('operator', nv)
		}
		/**
		 * 属性名改变后事件
		 */
		var fileListChange = function(ctl, nv) {// 字段名改变后事件
			if(nv)
				edit=false;
			nv=nv||ctl.value;
			var _store;
			var _valueStore = Ext.getCmp(moduleCode+"_setValue" + index);
			if (_valueStore)
				_valueStore.destroy();
//			var dataType;

			var _changeResult=getChange(nv,index);//获取类型相关的编辑器和操作符集合
			filterStore.getAt(index).set("inputType",_changeResult.inputType);
			_store=_changeResult.store;
			_valueStore=_changeResult.valueStore;
			var oper = Ext.getCmp(moduleCode+"_operator" + index);
			oper.clearValue();
			oper.store.loadData(_store);

			_valueStore.setWidth(getValueWidth());
			_valueStore.on("focus", focus);
			_valueStore.on("change", function(ctl, v, ov) {
				Ext.getCmp(moduleCode+"_fieldName" + index).focus();
				valueChange("setValue", ctl.dateFlag?v.dateFormat(this.format):v)
			});
			var valuePanel = Ext.getCmp(moduleCode+"_valuePanel" + index);
			var dataType=_changeResult.dataType;
			var type=_changeResult.type;
			valuePanel.add(_valueStore);
			valuePanel.doLayout(true);
			if(!edit)
			{
				valueChange("setValue", dataType=="4"?"0":""); 
				valueChange("operator", allOperator.EQ); 
				valueChange("fieldName", nv);
				valueChange("fieldLabel", findRecordValue(store, "fieldName", nv,
										"fieldLabel"));
				valueChange("fieldType", type||"string");
				valueChange("idRender",findRecordValue(store, "fieldName", nv,
										"idRender"));
				oper.setValue(allOperator.EQ);
				Ext.getCmp(moduleCode+"_setValue"+index).setValue("");
			}
		}
		/**
		 * 所有构造条件控件获焦事件
		 */
		function focus() {
			currentIndex = index;
		}
		/**
		 * 所有构造条件控件值改变后事件
		 * @param {String} name 控件基础名
		 * @param {String} v 值
		 */
		function valueChange(name, v) {
			var record = filterStore.getAt(index);
			record.set(name, v);
		}
		if(!edit)
			filterStore.insert(index, new filterStore.recordType({relation:(index>0)?"and":"",sort:index}));
		return {layout:"column",border:false,id:moduleCode+"_line"+index,items:[new Ext.form.ComboBox({
							columnWidth : .1,
							store : [["and", "并且"], ["or", "或者"]],
							value : (index > 0) ? "and" : "",
							disabled : (index == 0),
							id : moduleCode+"_relation" + index,
							triggerAction : "all",
							listeners : {
								focus : focus,
								change : function(ctl, v, ov) {
									valueChange("relation", v)
								}
							}
						}), new Ext.form.ComboBox({
							id : moduleCode+"_leftBr" + index,
							columnWidth : .1,
							store : ["(", "((", "((", "(((", "(((("],
							triggerAction : "all",
							regex :/^\({1,4}$/,
							editable : true,
							listeners : {
								focus : focus,
								change : function(ctl, v, ov) {
									valueChange("leftBr", this.isValid()?v:"")
									if(!this.isValid())
										this.setValue("")
								}
							}
						}), new Ext.form.ComboBox({
							id : moduleCode+"_fieldName" + index,
							columnWidth : .2,
							store : store,
							mode : "local",
							hiddenName : "value",
							triggerAction : "all",
							valueField : "fieldName",
							displayField : "fieldLabel",
							editable : false,
							listeners : {
								change : fileListChange,
								focus : focus
							}
						}), new Ext.form.ComboBox({
							columnWidth : .18,
							id : moduleCode+"_operator" + index,
							mode : "local",
							valueField : "value",
							displayField : "text",
							triggerAction : "all",
							store : new Ext.data.SimpleStore({
										fields : ["value", "text"]
									}),
							listeners : {
								focus : focus,
								change : operChange
							}
						})

				, {
					layout : "table",
					column : 1,
					id : moduleCode+"_valuePanel" + index,
					border : false,
					columnWidth : .32,
					items : new Ext.form.TextField({
								width:getValueWidth(),
								id : moduleCode+"_setValue" + index,
								listeners : {
									focus : focus,
									change : function(ctl, v, ov) {
										valueChange("setValue", v)
									}
								}
							})
				}, new Ext.form.ComboBox({
							id : moduleCode+"_rightBr" + index,
							columnWidth : .1,
							store : [")", "))", ")))", "))))"],
							mode : "local",
							triggerAction : "all",
							valueField : "value",
							displayField : "text",
							regex :/^\){1,4}$/,
							editable : true,
							listeners : {
								focus : focus,
								change : function(ctl, v, ov) {
									valueChange("rightBr",this.isValid()?v:"")
									if(!this.isValid())
										this.setValue("")
								}
							}
						})]}
	}
	/**
	 * 工具条
	 */
	var tool = new Ext.Toolbar({
				items : ["->",{
							xtype : "button",
							text : "增行",
							tooltip:"AddLine",
							icon : KANGSOFT+"/js/images/add_16.gif",
							listeners : {
								click : function() {
									panel.add(getLine(++lineIndex));
									panel.doLayout();
									currentIndex=lineIndex;
								}
							}
						},"-", {
							xtype : "button",
							text : "删行",
							tooltip:"DeleteLine",
							icon : KANGSOFT+"/js/images/delete.gif",
							handler : function() {
								if (currentIndex||(currentIndex+""=="0")) {
									Ext.Msg.confirm("删除提示", "你要删除此行吗?",
										function(v) {
											if (v == "yes"){
												deleteLine();
												if(currentIndex==firstIndex){
													var i=0;
													var _flag=true;
													filterStore.each(function(rec){
														if(!rec.get("delFlag"))
															return _flag=false;
														i++;
													})
													if(_flag)
													{
														panel.add(getLine(0));
														panel.doLayout();
														currentIndex=null;
														firstIndex=0;
													}
													else{
														firstIndex=i;
														var record = filterStore.getAt(firstIndex);
														record.set("relation","");
														Ext.getCmp(moduleCode+"_relation"+i).setValue("");
														Ext.getCmp(moduleCode+"_relation"+i).setDisabled(true);
													}
													
												}
											}
									})
								}else
									Ext.Msg.alert("删除提示","没有选择行");
							}
						},"-", {
							text : "全部清除",
							tooltip:"RemoveAll",
							icon : KANGSOFT+"/js/images/reset.png",
							handler : function() {
								delAllLine();
								panel.add(getLine(lineIndex));
								panel.doLayout();
							}
						},"-",{text:"刷新",tooltip:"Refresh",icon : KANGSOFT+"/js/images/refresh.png",handler:function(){
				        	if(currentFilter.id)
				        		afterTreeClick();
				        	else
				        		initFilter();
				        }},"-",{text:"保存",
				        	disabled:moduleCode?false:true,
							tooltip:"Save",
							icon : KANGSOFT+"/js/images/save.gif",handler:function(){
							if(!checkFilter())
								return;
							var data=getData();
							if(!data[0][0]&&!data[1][0])
							{
								Ext.Msg.alert("保存提示","没有修改条件,不需要保存");
								return;
							}
							Ext.MessageBox.prompt("筛选保存提示", "筛选名称:", function(btn,text){
							 	if(btn=="ok")
								 	{
								 		currentFilter.text=text;
								 		saveFilter(data);
								 	}
							 },this,false,currentFilter.text||"新增条件1");
				        }},"-", {
							text : "确认",
				        	disabled:moduleCode?false:true,
							tooltip:"Ok/Query",
							icon : KANGSOFT+"/js/images/search.png",
							handler : function() {
								if (checkFilter()) {
									if(true||filterStore.getModifiedRecords().length>0){
//										var respText=Ext.Ajax.request({
//											sync:true,
//											url:"query!putFilterInSession.action",
//											params:{
//												modified:getData()[0],
//												moduleCode:moduleCode
//											}
//										});
//										var result=Ext.util.JSON.decode(respText.conn.responseText);
										var result=okQuery();
										if(result.success){
											 var fn=callback.createCallback(result.success);
											 fn();
										}
									}
									 win.hide();
									 filterStore.commitChanges();
								}

							}
						},"-", {
							text : "关闭/返回",
							tooltip:"Cancel",
							icon : KANGSOFT+"/js/images/cancel.png",
							handler : function() {
								win.hide();
							}
						}],
				height : 25
			});
	/**
	 * 构造筛选条件面板
	 */
	var panel = new Ext.Panel({
				id : moduleCode+"_main_panel",
				tbar:tool,
				anchor:"101%",
				autoScroll:true,
				border:false,
				height:355,
				items : [{layout:"column",border:false,items:[{
							height:0,
							title : "关系",
							columnWidth:.1
						}, {
							title : "括号",
							height:0,
							columnWidth:.1
						}, {
							height:0,
							title : "字段名",
							columnWidth:.2
						}, {
							height:0,
							title : "运算符",
							columnWidth:.18
						}, {
							height:0,
							title : "内容",
							columnWidth:.32
						}, {
							height:0,
							title : "括号",
							columnWidth:.1
						}]}]
			});
	panel.add(getLine(0));
	
	var treeLoader = new Ext.tree.TreeLoader({
				dataUrl : "filterAction!getFilterTree.action",
				baseParams:{moduleCode:moduleCode}
			});
	/**
	 * 筛选条件树
	 */		
	var filterTree=new Ext.tree.TreePanel({//已保存的筛选树
				tools:[{qtip:"删除条件",handler:function(){
					if(currentFilter&&currentFilter.id)
					Ext.Msg.confirm("删除提示","你确认删除此条件吗?",function(v){
						if(v=="yes")
						Ext.Ajax.request({
							url:"filterAction!doDeleteFilter.action",
							params:{
								"head.id":currentFilter.id
							},
							success:function(resp, opt) {
								var text = Ext.util.JSON.decode(resp.responseText);
								if (text.success){
										Ext.Msg.alert("删除提示","删除成功!");
										currentFilter={attributes:{}};
										filterTree.getRootNode().reload();
									}
							}
						});
					})
				}},{id:"right",qtip:"停靠",hidden:true,handler:function(){filterTree.expand();filterTree.tools.left.show();this.hide();panel.doLayout(true,false)}},
							{id:"left",qtip:"收起条件树",handler:function(){filterTree.collapse();treeColFlag=!treeColFlag;changeValueWidth();filterTree.tools.right.show();this.hide()}}],				
				autoScroll : true,
				region:"west",
				width : 130,
				lines : true,
				rootVisible : true
			});
	filterTree.on("expand",function(p){
		treeColFlag=!treeColFlag;changeValueWidth();
	})
	var treeRoot = new Ext.tree.AsyncTreeNode({
				id : "0",
				text : "root",
				draggable : false
			})
	filterTree.setRootNode(treeRoot);
	filterTree.loader = treeLoader;
	
	initFilter();
	filterTree.on("click",function(node){
		if(node.id==currentFilter.id)
			return;
		if(!node.parentNode)
		{
			if(currentFilter.id)
			{
				currentFilter={attributes:{}};
				delAllLine();
				panel.add(getLine(0));
				panel.doLayout();
			}
			return;
		}
		if(store.getCount()==0)
			store.load({});
		currentFilter=node;
		afterTreeClick();
	})

/**
 * 筛选面板
 */
function addFilter(data){
//	alert(1)
	
	function add(filter){	
		if(!Ext.isObject(filter))
			throw new Error("手动增加筛选条件不符合规定, 只能是对象或对象数组");
		if(!filter.fieldName)
			return;
		var result=getChange(filter.fieldName);
		if(!result||!result.store)
			return;
		if(filter.operator){
			var hasFlag=false;
			Ext.each(result.store,function(rec){
				if(rec[0]==filter.operator){
					hasFlag=true;
					return false;
				}
			});
			if(!hasFlag)
				throw new Error("指定的:'"+filter.fieldName+"'列的运算符不在允许范围内,请检查!");
		}
		var record={};
		store.each(function(rec){
			if(rec.data.fieldName==filter.fieldName)
			{
				record=rec.data;
				return false;
			}
		})
		record.operator=allOperator.EQ;
		Ext.applyIf(filter,{
			fieldLabel:record.fieldLabel,
			fieldType:record.fieldType,
			inputType:record.inputType,
			inputSql:record.inputSql,
			method:record.method,
			idRender:record.idRender,
			operator:record.operator
		});
		Ext.apply(filter,{
				relation:(lineIndex>0)?"and":""
			}
		)
		if(lineIndex==0&&!filterStore.getAt(0).data.fieldName){
//			filterStore.removeAll();
			delAllLine();
			lineIndex=-1;
		}
		var filterRec=new filterStore.recordType(filter);
		var _index=win.customFilter[filter.fieldName]||sortInfo[filter.fieldName];
		if(_index+""==0||_index){
			var _rec=filterStore.getAt(_index);
			for(var p in filter)
				_rec.set(p,filter[p]);
			currentIndex=_index;
		}else
		{
			filterRec.data.custom="1";
			filterRec.data.sort=lineIndex+1;
			filterStore.insert(++lineIndex, filterRec);
			win.customFilter[filter.fieldName]=lineIndex;
			currentIndex=lineIndex;
		}
		addLineFromRecord(currentIndex,filterRec);
	}
	if(Ext.isArray(data)){
		Ext.each(data,function(f){
			add(f);
		})
	}else
		add(data);
}
var getFilters=function(flag){
	if(flag){
		
	}else
		return filterStore.data;
}
var win=Ext.getCmp("win"+moduleCode);
if(!win)
	win = new Ext.Window({
			plain : true,
			resizable : false,
			draggable : true,
			loadMask : true,
			id : "win"+moduleCode,
			modal : true,
			layout:"border",
			closeAction : "hide",
			width : 650,
			height : 400,
			closable:false,
			customFilter:{},
			title : "<img src='"+KANGSOFT+"/js/images/search.png' style='vertical-align: middle;'>筛选窗体</img>",
			items : [filterTree,{layout:"anchor",region:"center",items:[panel]}],
			allOperator:allOperator,
			addFilter:addFilter,//自增加筛选行
			getFilters:getFilters,
			clearFilter:function(afterClear){//手动清除所有行
				delAllLine();
				panel.add(getLine(lineIndex));
				panel.doLayout();
				okQuery();
				if(afterClear)
					afterClear.call();
			},
			run:function(){
//				if (filterStore.getModifiedRecords().length>0&&checkFilter()) {
//					var result=okQuery();
				var result=this.save();
				if(result){
					 var fn=callback.createCallback(result.success);
					 fn();
					filterStore.commitChanges();
				}
//				}
			},
			save:function(){
				if (filterStore.getModifiedRecords().length>0&&checkFilter()) {
					var result=okQuery();
					if(!result.success){
						Ext.Msg.alert("操作提示","保存条件失败");
					}
					return result;
				}
				return false;
			}
		});
	return win;
}

FilterProxy=function(config){
	Ext.apply(this,config);
	FilterProxy.constructor.call(this);
}
Ext.extend(FilterProxy,Object,{
	addFilter:function(data){
		var obj=this;
		function add(filter){	
			var _fname=obj[filter.fieldName]||filter.fieldName;
			filter.fieldName=_fname;
		}
		if(Ext.isArray(data)){
			Ext.each(data,function(f){
				add(f);
			})
		}else
			add(data);
		obj.win.addFilter(data);
	},
	run:function(){this.win.run()},
	save:function(){this.win.save()}
})

 使用部分代码如下:

 

/** ******************************************筛选*************************************************** */
					var reloadStore =function(flag)
					{
						if(flag)
							ds.load({params:{start:0,limit:15}})
					}
					var fieldsDef = new Ext.data.JsonStore({
						fields :  ['fieldName','fieldLabel',
									'fieldType','inputType',"idRender","store",
									'disValue', 'disText'],
						data : [{
									fieldName : 's.itemClassId',
									fieldLabel : '大类',
									fieldType : 'string',
									idRender:'itemClass_hql'
								}, {
									fieldName : 's.ornaClassId',
									fieldLabel : '小类',
									fieldType : 'string',
									idRender:'ornaClass_hql'
								}, {
									fieldName : 's.sizeName',
									fieldLabel : '尺寸/规格',
									fieldType : 'string'
								}, {
									fieldName : 's.errorStart',
									fieldLabel : '误差起始范围',
									fieldType : 'string'
								}, {
									fieldName : 's.errorEnd',
									fieldLabel : '误差截止范围',
									fieldType : 'string'
								}]
					});
					//创建筛选grid
					var filter =createFilter(fieldsDef,'040623',reloadStore);

 注:其中的后台代码部分,根据项目的具体情况由使用者自己发挥开发。建议将相应的筛选条件部分放入session,session的ID可以设置为模块代码,便于与其它模块的筛选功能部分的条件区分。此筛选功能还有待进一步完善,如果有使用到的朋友在开发过程中有什么更好的建议,希望给予支持。(QQ:329365156)

  • 大小: 40.4 KB
4
1
分享到:
评论
1 楼 cn-done 2010-11-21  
这个的设计思路有点想BugFree的条件选择

相关推荐

Global site tag (gtag.js) - Google Analytics