`
kangsoft
  • 浏览: 71777 次
  • 性别: 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的条件选择

相关推荐

    ExtJs:收集基于ExtJs扩展的一些控件

    这个文件可能是对一些自定义或第三方开发的ExtJs控件的概述,它可能包括了各种特定用途的组件,如日历控件、拖放功能、树形视图、图表插件等。这些控件通常是为了满足特定项目需求或者优化原有组件性能而创建的。...

    Extjs 5 日期时间控件

    在ExtJS 5中,日期时间控件是开发用户界面时经常会用到的组件,它允许用户选择和输入日期及时间值。本篇文章将深入探讨ExtJS 5的日期时间控件及其特点。 首先,ExtJS 5 的日期时间控件(DateTimeField)结合了日期...

    extjs扩展年度控件,EXTJS里的时间控件的年度重写

    然而,有时开发人员可能需要对这些控件进行自定义,以满足特定业务需求,比如在本例中,我们需要扩展EXTJS的时间控件以实现“年度”选择的功能。 EXTJS的Date Picker默认提供了日、月、年的选择,但可能并不完全...

    Extjs6 日期时间控件

    在EXTJS6中,日期时间控件是一种强大的用户界面组件,它将传统的日期选择器与时间选择器结合在一起,提供了一种便捷的方式来输入和编辑日期和时间数据。这个控件在许多应用程序中都非常实用,特别是在那些需要精确...

    extjs时间控件精确秒

    在EXTJS这个强大的JavaScript框架中,时间控件是开发者经常使用的组件之一,尤其在构建复杂的Web应用程序时。EXTJS的时间控件允许用户选择或输入时间,通常以小时、分钟和秒为单位,提供了用户友好的界面和丰富的...

    extjs日期+时间控件

    5. **事件处理**:ExtJS控件通常支持多种事件,如`select`事件(当用户选择一个日期或时间时触发),开发者可以绑定回调函数来响应这些事件,进行进一步的数据处理或验证。 6. **本地化**:对于国际化的应用,日期...

    extjs3.0 日期时间控件

    标题中的"extjs3.0 日期时间控件"指的是ExtJS 3.0框架中的DateTimeField组件,这是一个组合了日期选择器和时间选择器的控件,允许用户以交互的方式选择精确的日期和时间。这个控件通常用于表单中,提供了一种直观且...

    extjs 多文件上传控件

    在ExtJS中,多文件上传控件是开发人员常用的一种功能,用于在网页上实现批量上传多个文件。这种控件允许用户一次性选择并上传多个文件,极大地提升了用户体验。 在ExtJS中实现多文件上传,主要涉及到以下几个关键...

    extjs6 日期时间控件

    extjs 6 的日期时间控件,不能用我铲脸

    extjs 4.0 日期时间控件

    在标题中提到的"extjs 4.0 日期时间控件",是指ExtJS 4.0框架中的DateTime组件,这是一个用于在Web应用中输入和显示日期与时间的控件。 描述中提到了这个控件是经过修改的中文版本。原版可能是英文,但通过定制,...

    ExtJS下拉列表树控件

    在ExtJS中,下拉列表树控件(ComboBox Tree)是常见的组件之一,它结合了下拉列表和树结构,提供了更丰富的用户界面。这个控件允许用户从一个层级化的数据结构中进行选择,非常适合于展示有层次关系的数据。 在创建...

    extjs扩展的月份控件

    同事写的extjs月份扩展控件,可以直接调用,用于只要求显示月份不显示日期的项目

    ExtJs日期时间选择控件

    在ExtJs中,日期时间选择控件是开发人员常用的一个组件,它允许用户方便地选择日期和时间,极大地提升了用户体验。本篇文章将深入探讨ExtJs日期时间选择控件的使用、功能以及优化后的特性。 1. **ExtJs日期时间选择...

    ExtJS 通用查询

    在本例中,我们关注的是ExtJS中的通用查询功能,这是一个允许用户动态构建多条件查询的高级搜索机制。 1. **动态添加查询条件**:通用查询界面允许用户根据需求动态添加多个查询条件。这意味着用户可以自由地选择要...

    extjs年份控件(只显示年,无月日时分秒)

    Extjs DateField控件 - 只选择年份(找了很久发现网上只有选择年月的控件,于是基于extjs年月控件设计了只选择年份的控件)

    extjs网页控件开发

    这种控件在许多数据筛选和导航场景中非常常见。在一级、二级、三级联动下拉框中,选择一个选项将影响下一个下拉框的显示内容,提供了一种层次清晰的导航方式。在ExtJS中,这通常通过组合框(ComboBox)组件和数据...

    extjs3.2、3.3 时间控件 日期控件扩展

    在3.2和3.3版本中,ExtJS的时间控件(DateTimeField)和日期控件(DateField)是开发者常用的功能组件,用于处理用户输入的日期和时间数据。这些控件具有高度可定制性,可以满足各种界面和功能需求。 1. **时间控件...

    EXTJS时间控件年月日时分秒

    在EXTJS中,时间控件是常见的交互元素,允许用户选择特定的时间,包括年、月、日、时、分和秒。这篇文档将深入探讨EXTJS中的时间控件及其使用方法。 首先,EXTJS时间控件的设计理念是为了提供用户友好的时间选择...

    extjs 微调控件,时间微调控件,微调,javascript 微调

    在ExtJS中,微调控件(Spinner)是一种用户界面组件,它允许用户通过点击向上或向下的箭头以微小增量增加或减少数值,常见于输入框旁边,提供一种方便的数值调整方式。这个控件在处理精确输入或者范围限制的数值时...

Global site tag (gtag.js) - Google Analytics