优化jeecg底层高级查询,支持bool值和下拉框查询
最近在用jeecg做项目,在使用高级查询的时候发现它不支持布尔值的查询以及列表的下拉框的查询,所以小编修改了底层代码,完善了高级查询,现在与大家一起分享。先上一张图给大家看一下修改前的高级查询。
它只支持了文本的查询以及日期格式的查询,很难满足在使用过程中的要求。所以小编把他的功能丰富了一下,下面把源码分享给大家。
首先先简单介绍一下jeecg高级查询的原理,一切的秘密都在DataGridTag这个标签类里面,在打开一个页面的时候,这个类会对页面的左右变迁进行初始化,以及对高级查询的页面进行构造。当你在jsp页面中对datagrid设置属性queryBuilder="true",页面中就会出现高级查询的按钮,点击高级查询,就会弹出,DataGridTag这个类在初始化是生成的高级查询的页面。先看一下生彻骨页面的源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
fieldArray.append( " [ " ); for ( int i= 0 ;i<columnList.size();i++){ DataGridColumn col =columnList.get(i); if ( "opt" .equals(col.getField())) continue ; //忽略操作虚拟字段 if (!col.isHidden()) { fieldArray.append( " {'fieldId':'" + ((col.getQueryChangeCol() != null && !col.getQueryChangeCol().equals( "" )) ? col.getQueryChangeCol() : getDBFieldName(col.getField()))+ "','fieldName':'" +col.getTitle()+ "'" ); if (col.getEditor()!= null ){ fieldArray.append( ",editor:'" +col.getEditor()+ "'" ); } if (col.getReplace()!= null ){ String str = col.getReplace(); fieldArray.append( ",replaceid:'" +str+ "'" ); } fieldArray.append( "}" ); if (i<columnList.size()- 1 ){ fieldArray.append( "," ); } } } |
datagrid这个表格列支持一个replace属性,例如:
<t:dgCol title="单据状态" field="billstate" editor="combobox" hidden="false" queryMode="single" formatter="billstateFormat" width="120" replace="自由态_0,提交_1,审批_2"></t:dgCol>
这是会在主界面根据不同得知,显示不同的文字,类似于表格的自定义转换,我们要在高级查询中支持下拉框和bool值也要利用这个属性。上面的代码就是就是获取到主界面忠表格所有现实的列,构造高级查询字段这一列供你查询,注意这一段代码
1
2
3
|
if (col.getReplace()!= null ){ String str = col.getReplace(); fieldArray.append( ",replaceid:'" +str+ "'" );<br>}<br>它的作用就是在构造你可以查询的的字段中,如果某一个列的replace属性有值,说明他在展示中进行了值得转换,同时也说明 他在高级查询中应该是一个下拉框供人选择,所以我们在构造字段列的时候不能单单构造到他的fieldId,fieldName,还要记录一下它设置的replace的值,方便你选到这个进行查询时,他会在值录入的那一列自动转换成一个下拉框,并对下拉框进行赋值。<br>构造好这一切之后,要做的就是对高级查询的页面的treegrid的每一列进行样式的设置,这里面最重要的就是界面中字段列的下拉框的选择改变事件,让我们来看下: |
appendLine(sb,"for(var i=0;i<data.length;i++){"); appendLine(sb,"if(value == data[i]['fieldId']){"); appendLine(sb,"return data[i]['fieldName'];"); appendLine(sb,"}"); appendLine(sb,"}"); appendLine(sb,"return value;"); appendLine(sb,"},editor:{"); appendLine(sb,"type:'combobox',"); appendLine(sb," options:{"); appendLine(sb,"valueField:'fieldId',"); appendLine(sb,"textField:'fieldName',"); appendLine(sb,"data: "); sb.append(fieldArray); appendLine(sb," , "); appendLine(sb, "required:true,onSelect : function(record) { debugger;"); appendLine(sb,"var opts = $('#"+name+"tg').treegrid('getColumnOption','value');"); appendLine(sb, " if(record.editor != null && record.editor != ''){"); appendLine(sb, " opts.editor={'type':record.editor};"); appendLine(sb, "var tr = $(this).closest('tr.datagrid-row');"); appendLine(sb, "var index = parseInt(tr.attr('node-id'));"); appendLine(sb, " $($('#"+name+"tg').treegrid('getEditors', index)[3].target).val('');"); appendLine(sb, " $($($('#"+name+"tg').treegrid('getEditors', index)[3].target).next().find('input')[1]).val('');"); appendLine(sb, " $('#"+name+"tg').treegrid('endEdit', index);"); appendLine(sb, " $('#"+name+"tg').treegrid('beginEdit', index);"); appendLine(sb, " var arrayList = []; "); appendLine(sb, " if (record.replaceid != null) {var jsonid = record.replaceid;"); appendLine(sb, " var idList = jsonid.split(',');"); appendLine(sb, " if (opts.editor.type == 'combobox'){ "); appendLine(sb, "$.each(idList,function(i,n){"); appendLine(sb, "var obj={};"); appendLine(sb, "var namelist=n.split('_');"); appendLine(sb, "obj['relationId']=namelist[1];"); appendLine(sb, "obj['relationName']=namelist[0];"); appendLine(sb," if(namelist[2] != null){"); appendLine(sb," obj['ifnull']=namelist[2]}"); appendLine(sb, "arrayList.push(obj);"); appendLine(sb, "}); "); appendLine(sb, "$($('#"+name+"tg').treegrid('getEditors', index)[3].target).combobox({"); appendLine(sb, " valueField:'relationId',"); appendLine(sb, "textField:'relationName' "); appendLine(sb, " })"); appendLine(sb, "$($('#"+name+"tg').treegrid('getEditors', index)[3].target).combobox('loadData',arrayList);$($($('#"+name+"tg').treegrid('getEditors', index)[3].target).next().find('input')[0]).css('width','70px');"); appendLine(sb, "if(arrayMap==null){arrayMap = {};};arrayMap[record.fieldId]=arrayList;}}"); appendLine(sb, "else{"); appendLine(sb, "opts.editor={'type':record.editor,option:{ valueField:'relationId', textField:'relationName' ,required:true }}}"); appendLine(sb, " }else{"); appendLine(sb, " opts.editor='text';"); appendLine(sb, "var tr = $(this).closest('tr.datagrid-row');"); appendLine(sb, "var index = parseInt(tr.attr('node-id'));"); appendLine(sb, " $($($('#"+name+"tg').treegrid('getEditors', index)[3].target).next().find('input')[1]).val('');"); appendLine(sb, " $('#"+name+"tg').treegrid('endEdit', index);"); appendLine(sb, " $('#"+name+"tg').treegrid('beginEdit', index);"); appendLine(sb, " }"); appendLine(sb, "}"); appendLine(sb," }}\">字段</th>");
关键的就是上面的代码中表蓝色的部分,他就是字段列下拉框的改变事件,先看一下我调整后的效果
1
|
<br>我们来分析一下代码, |
var opts = $('#"+name+"tg').treegrid('getColumnOption','value');//获取到所选的字段这一行列标题为值得这一列的属性对象
然后他会去获取你在主界面列展示中地这个属性设置的editor的值,然后赋给value这一列,其实也就是把设置好的类型赋值给他,例如:
<t:dgCol title="单据状态" field="billstate" editor="combobox" hidden="false" queryMode="single" formatter="billstateFormat" width="120" replace="自由态_0,提交_1,审批_2"></t:dgCol>
你设置了editor="combobox"那么你在高级查询界面选择了单据转改进行查询,相应的它的值那一列就会变成下拉框。
下面就是给值得下拉框赋值的问题了,
if (record.replaceid != null) {
var jsonid = record.replaceid;//之前在构造字段列的时候会记录每一个字段是否有replace值,如果有,先获取到它的replace值,例如:replace="自由态_0,提交_1,审批_2" var idList = jsonid.split(','); if (opts.editor.type == 'combobox'){ $.each(idList,function(i,n){//根据逗号分隔的数组,进行对下拉框数据源进行组装 var obj={}; var namelist=n.split('_'); obj['relationId']=namelist[1];//下拉框隐藏的id obj['relationName']=namelist[0];//下拉框现实的text if(namelist[2] != null){ obj['ifnull']=namelist[2]}//ifnull这个是方便数据哭某些表的integer的类型的字段忘记选中分空,所以会出现一些数据为空的情况,你也可以根据replace属性的设置,对空值转换 arrayList.push(obj); }); $($('#"+name+"tg').treegrid('getEditors', index)[3].target).combobox({//制定下拉框的属性对应数据源的属性 valueField:'relationId', textField:'relationName' }) $($('#"+name+"tg').treegrid('getEditors', index)[3].target).combobox('loadData',arrayList);$($($('#"+name+"tg').treegrid('getEditors', index)[3].target).next().find('input')[0]).css('width','70px');//对下拉框进行数据源的绑定,注意在获取下拉框的时候一定要像这样$($('#"+name+"tg').treegrid('getEditors', index)[3].target)获取到他下拉框的combobox控件进行时间绑定,否则数据是绑定不了的。 if(arrayMap==null){arrayMap = {};};
arrayMap[record.fieldId]=arrayList;//大家注意这一行代码是要记录这一个字段对应的下拉框的数据源,方便下拉框选择了值之后,将下拉框的valueField转成textField。以及当你第二次打开高级查询时,查询历史的查询记录,同样也要根据这个将下拉框的值进行转换,非常重要。
}}
下面就涉及到了高级查询界面的确定按钮,先看一下代码
appendLine(sb, "function queryBuilderSearch() { "); appendLine(sb, " var json = view();"); appendLine(sb, " $('#_sqlbuilder').val(json); "); appendLine(sb, " var isnew=true; "); appendLine(sb, "for(var i=0;i< "+name+"his.length;i++){"); appendLine(sb, " if("+name+"his[i]&&"+name+"his[i].json==json){"); appendLine(sb, " isnew=false;"); appendLine(sb, " }"); appendLine(sb, "}"); appendLine(sb, "if(isnew && json!='[]'){"); appendLine(sb, " "+name+"his.push({name:'Query'+"+name+"his.length,json:json});saveHistory();"); appendLine(sb, "var name= 'Query'+( "+name+"his.length-1);"); appendLine(sb, " var name= 'Query'+("+name+"his.length-1);"); appendLine(sb, "appendTree("+name+"his.length-1,name);"); appendLine(sb, "}"); appendLine(sb, " var t = $('#" + name + "tg');"); appendLine(sb, " var data = t.treegrid('loadData',[]);"); appendLine(sb, " " + name + "search();$('#_sqlbuilder').val('');$('#"+name+"_qbwin').window('close')"); appendLine(sb, " }");
appendLine(sb, "function view(){"); appendLine(sb,"save();"); appendLine(sb,"var t = $('#"+name+"tg');"); appendLine(sb,"var data = t.treegrid('getData');"); //// 增加布尔类型的值. appendLine(sb,"for (var i = 0; i < data.length; i++) {
if(jQuery.isEmptyObject(arrayMap)){arrayMap=storage.get('arrayMap');}");//因为我们下拉框的数据源会进行缓存,所以第二次进入高级查询时,map会是空的,我们要去缓存中 获取之前的map数据 appendLine(sb," if (arrayMap != null){var list = arrayMap[data[i].field];if (list != null){"); appendLine(sb," if(data[i].rember == null || data[i].rember==''){$.each(list,function(j,n){"); appendLine(sb," if(n.relationId==data[i].value){"); appendLine(sb," data[i].rember=data[i].value;if(n.ifnull != null){data[i].ifnull = n.ifnull;};data[i].replace = n.relationName;");//在要缓存的记录数据中增加replace属性,记录下拉框值对应的文本显示 appendLine(sb, " }})} else{data[i].value=data[i].rember;}}} "); appendLine(sb," }"); //// 增加布尔类型的值。 appendLine(sb,"return JSON.stringify(data) ;");
appendLine(sb,"function save(){"); appendLine(sb," var t = $('#"+name+"tg');"); appendLine(sb," var nodes = t.treegrid('getData');"); appendLine(sb," for (var i = 0; i < nodes.length; i++) {"); appendLine(sb," t.treegrid('endEdit',nodes[i].id);} "); appendLine(sb," for (var i = 0; i < nodes.length; i++) {"); appendLine(sb," if(jQuery.isEmptyObject(arrayMap)){arrayMap=storage.get('arrayMap');} if (arrayMap != null) {var list = arrayMap[nodes[i].field];if (list != null){"); appendLine(sb, " $.each(list,function(j,n){t.treegrid('beginEdit',nodes[i].id);"); appendLine(sb," if(n.relationId==nodes[i].value){"); appendLine(sb," nodes[i].replace = n.relationName; nodes[i].rember = n.relationId;if(n.ifnull != null){nodes[i].ifnull = n.ifnull;}; nodes[i].value = nodes[i].replace;}"); appendLine(sb, " t.treegrid('update',{id:nodes[i].id,row:nodes[i]})})}}" ); appendLine(sb," } "); appendLine(sb,"saveHistory();storage.set('arrayMap',JSON.stringify(arrayMap));");//缓存字段的下拉框的数据源 appendLine(sb," }");
重要的就是对这三个js方法进行修改,下面一次为大家讲解这三个方法:
1
|
view()方法主要是对查询界面的treegrid的数据进行一下加工,因为查询的记录会被缓存,而传到服务端的只会是下拉框的value,以方便再次查看, |