在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&¤tFilter.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)