在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)