基于ExtJs框架的B/S高级查询界面

把昨天做的高级查询界面完善了一下,支持动态添加多个查询条件、定义逻辑关系,支持整形、浮点、字符串、日期、布尔值、自定义选择列表的录入,通过Ext.data.JsonStore可方便的与服务器交互,具体不多说了,看下面示例,曾经做过的朋友不妨交流一下。

 

样图:

 

示例:

  1. <DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html><head><title>XXX系统V1.0</title>
  3. <meta name="Author" contect="彭国辉">
  4. <meta name="Keywords" content="高级查询界面" />
  5. <meta name="Description" content="http://blog.csdn.net/nhconch" />
  6. <meta http-equiv="Content-Type" content="text/html; charset=utf8">
  7. <link rel="stylesheet" type="text/css" href="resources/css/ext-all.css">
  8. <script type="text/javascript" src="adapter/ext/ext-base.js"></script>
  9. <script type="text/javascript" src="ext-all.js"></script>
  10. <script type="text/javascript" src="source/locale/ext-lang-zh_CN.js"></script>
  11. <script type="text/javascript">
  12. Ext.BLANK_IMAGE_URL = 'resources/images/default/s.gif';
  13. Ext.onReady(function () {
  14. var dsPQ=new Ext.data.JsonStore({
  15.    data:[],
  16.    fields:["idx","relation","leftParenthesis","fieldname","operator","value","rightParenthesis"] 
  17. });
  18. var fieldsDef = new Ext.data.JsonStore({
  19.     fields: ['value','text','type','data'],
  20.     data:[
  21.         {value:'A.Billno',text:'字符串',type:'string'},
  22.         {value:'A.Date',text:'日期',type:'date'},
  23.         {value:'A.boolean',text:'布尔',type:'boolean'},
  24.         {value:'A.int',text:'整形',type:'int'},
  25.         {value:'A.float',text:'浮点',type:'float'},
  26.         {value:'A.lookup',text:'Lookup',type:'lookup',data:[['AA','list1'],['BB','list2'],['CC','list3']]},
  27.         {value:'A.datalist',text:'自定义列表',type:'lookup',data:[[10,'xxxx1'],[20,'xxxx2'],[30,'xxxx3'],[11,'xxxx11'],[21,'xxxx21'],[31,'xxxx31'],[12,'xxxx22'],[22,'xxxx22'],[32,'xxxx32'],[13,'xxxx13'],[23,'xxxx23'],[33,'xxxx33'],[14,'xxxx14'],[24,'xxxx24'],[34,'xxxx3'],[15,'xxxx15'],[25,'xxxx25'],[35,'xxxx35'],[16,'xxxx16'],[26,'xxxx26'],[36,'xxxx36']]}
  28.     ]
  29. });
  30. /*
  31.   作者 :  彭国辉 2008-8-30
  32.   网站 :  http://kacarton.yeah.net/
  33.   博客 :  http://blog.csdn.net/nhconch
  34.   邮箱 :  kacarton(a)sohu.com
  35.   文章为作者原创,转载前请先与本人联系,转载请注明文章出处、保留作者信息,谢谢支持!
  36. */
  37. var numericOp = datetimeOp = new Ext.data.SimpleStore({
  38.     fields: ['value','text'],
  39.     data : [['=','='],['<>','<>'],['<','<'],['<=','<='],['<','>'],['>=','>='],['is null','空白'],['is not null','非空白']]
  40. });
  41. var stringOp = new Ext.data.SimpleStore({
  42.     fields: ['value','text'],
  43.     data : [['=','='],['<>','<>'],['<','<'],['<','>'],
  44.     ["like '|%'",'以...开头'],["like '%|'",'以...结尾'],["like '%|%'",'包含字符'],["not like '%|%'",'不包含字符'],
  45.     ['is null','空白'],['is not null','非空白']]
  46. });
  47. var lookupOp = booleanOp = new Ext.data.SimpleStore({
  48.     fields: ['value','text'],
  49.     data : [['=','='],['<>','<>'],['is null','空白'],['is not null','非空白']]
  50. });
  51. var objGridTextEditor = new Ext.grid.GridEditor(new Ext.form.TextField());
  52. //var objGridMemoEditor = new Ext.grid.GridEditor(new Ext.form.TextArea());
  53. var objGridDateEditor = new Ext.grid.GridEditor(new Ext.form.DateField({format:'Y-m-d'}));
  54. var objGridIntegerEditor = new Ext.grid.GridEditor(new Ext.form.NumberField({allowBlank:false,allowNegative:false,allowDecimals:false}));
  55. var objGridFloatEditor = new Ext.grid.GridEditor(new Ext.form.NumberField({allowBlank:false,allowNegative:false}));
  56. var objGridBooleanEditor = new Ext.grid.GridEditor(new Ext.form.ComboBox({
  57.     store: [[true,'是'],[false,'否']],
  58.     mode: 'local',
  59.     readOnly: true,
  60.     triggerAction: 'all',
  61.     allowBlank: false,
  62.     editable: false,
  63.     forceSelection: true,
  64.     blankText:'请选择...'
  65. }));
  66. var objGridLookupEditor;
  67. function fileListChange(field,newValue,oldValue){
  68.     //alert(field);
  69. }
  70. function findRecordValue(store,prop, propValue,field){
  71.     var record;
  72.     if(store.getCount() > 0){
  73.         store.each(function(r){
  74.             if(r.data[prop] == propValue){
  75.                 rrecord = r;
  76.                 return false;
  77.             }
  78.         });
  79.     }
  80.     return record ? record.data[field] : '';
  81. }
  82. function displayOperator(v){
  83.     switch(v){
  84.         case 'is null': return '空白';
  85.         case 'is not null': return '非空白';
  86.         case "like '|%'": return '以...开头';
  87.         case "like '%|'": return '以...结尾';
  88.         case "like '%|%'": return '包含字符';
  89.         case "not like '%|%'": return '不包含字符';
  90.         default: return v;
  91.     }
  92. }
  93. function displayValue(v, params, record){
  94.     var dataType = findRecordValue(fieldsDef,'value',record.get('fieldname'),'type');
  95.     var operator = record.get('operator');
  96.     if (operator=='is null'||operator=='is not null') return '';
  97.     switch(dataType){
  98.         case 'date': return v ? v.dateFormat('Y-m-d'): '';
  99.         case 'boolean': return (v?'是':'否');
  100.         case 'lookup': var data = findRecordValue(fieldsDef,'value',record.get('fieldname'),'data');
  101.             for (var i=0; i<data.length; i++)
  102.                 if (v==data[i][0]) return data[i][1];
  103.             //return data[v] + ','+data[v,0]+','+data[0,0];
  104.             //return data[v,0]+','+data[0,0];
  105.         /*case 'string':
  106.         case 'int':
  107.         case 'float':*/
  108.         default: return v;
  109.     }
  110. }
  111. var qRowData = Ext.data.Record.create([
  112.     {name:'idx',type:'int'},
  113.     {name:'relation',type:'string'},
  114.     {name:'leftParenthesis',type:'string'},
  115.     {name:'fieldname',type:'string'},
  116.     {name:'operator',type:'string'},
  117.     {name:'value',type:'string'},
  118.     {name:'rightParenthesis',type:'string'}
  119. ]);
  120. var colM=new Ext.grid.ColumnModel([
  121.     {
  122.         header:"关系",
  123.         dataIndex:"relation",
  124.         width:50,
  125.         renderer: function(v){return (v=='and'?'并且':'或者')},
  126.         editor:new Ext.form.ComboBox({ 
  127.             store: [['and','并且'],['or','或者']],
  128.             mode: 'local', 
  129.             readOnly: true, 
  130.             triggerAction: 'all', 
  131.             allowBlank: false,
  132.             //valueField: 'value', 
  133.             //displayField: 'text', 
  134.             editable: false, 
  135.             forceSelection: true, 
  136.             blankText:'请选择'
  137.         })
  138.     },{
  139.         header:"括号",
  140.         dataIndex:"leftParenthesis",
  141.         width:40,
  142.         editor:new Ext.form.ComboBox({
  143.             store: ['(','((','((','(((','(((('],
  144.             mode: 'local',
  145.             triggerAction: 'all',
  146.             valueField: 'value',
  147.             displayField: 'text',
  148.             editable: false
  149.         })
  150.     },{
  151.         header:"字段名",
  152.         dataIndex:"fieldname",
  153.         width:130,
  154.         //renderer: function(v, params, record){return record.data['fieldname']},
  155.         renderer: function(v){return findRecordValue(fieldsDef,'value',v,'text');},
  156.         editor:new Ext.form.ComboBox({
  157.             store: fieldsDef,
  158.             mode: 'local',
  159.             triggerAction: 'all',
  160.             valueField: 'value',
  161.             displayField: 'text',
  162.             editable: false,
  163.             listeners:{change:fileListChange}
  164.         })
  165.     },{
  166.         header:"运算符",
  167.         width:80,
  168.         dataIndex:"operator",
  169.         renderer: displayOperator
  170.     },{
  171.         header:"内容",
  172.         dataIndex:"value",
  173.         width:130,
  174.         renderer: displayValue
  175.     },{
  176.         header:"括号",
  177.         width:40,
  178.         dataIndex:"rightParenthesis",
  179.         editor:new Ext.form.ComboBox({
  180.             store: [')','))',')))','))))'],
  181.             mode: 'local',
  182.             triggerAction: 'all',
  183.             valueField: 'value',
  184.             displayField: 'text',
  185.             editable: false
  186.         })
  187.     }
  188. ]);
  189. var grdDPQuery = new Ext.grid.EditorGridPanel({
  190.     height:500,
  191.     width:490,
  192.     renderTo:"hello",   
  193.     cm:colM,
  194.     sm:new Ext.grid.RowSelectionModel({singleSelect:false}),
  195.     store:dsPQ,
  196.     region:'center',
  197.     border: false,
  198.     enableColumnMove: false,
  199.     enableHdMenu: false,
  200.     loadMask: {msg:'加载数据...'},
  201.     clicksToEdit:1,
  202.     tbar:[
  203.         {text:'添加',handler:function(){
  204.                 var count = dsPQ.getCount();
  205.                 var r = new qRowData({idx:dsPQ.getCount(),relation:'and',leftParenthesis:'',fieldname:'',operator:'=',value:'',rightParenthesis:''});
  206.                 dsPQ.commitChanges();
  207.                 dsPQ.insert(count,r);
  208.             }
  209.         },
  210.         {text:'删除',handler:function(){
  211.                 //store = grid.getStore();
  212.                 var selections = grdDPQuery.getSelectionModel().getSelections();
  213.                 for(var i = 0; i < selections.length; i++){ 
  214.                     dsPQ.remove(selections[i]); 
  215.                 }
  216.             }
  217.         },
  218.         {text:'全部清除',handler:function(){dsPQ.removeAll();}},
  219.         {text:'检查',handler:function(){if(checkFilter(grdDPQuery)) alert('检查通过!');}},
  220.         {text:'显示内容',handler:function(){var pv = document.getElementById('preview'); pv.value=getFilter(grdDPQuery)}},
  221.         {text:'显示文本',handler:function(){var pv = document.getElementById('preview'); pv.value=getFilterText(grdDPQuery)}}
  222.     ],
  223.     listeners: {
  224.         afteredit: function(e){
  225.             if (e.column==2/*e.field=='fieldname'*/){
  226.                 var oldDataType = findRecordValue(fieldsDef,'value',e.originalValue,'type');
  227.                 var newDataType = findRecordValue(fieldsDef,'value',e.value,'type');
  228.                 if (oldDataType!=newDataType){
  229.                     e.record.set('operator', '=');
  230.                     e.record.set('value', '');
  231.                 }
  232.                 //e.grid.colModel.setEditor(1, new Ext.grid.GridEditor(new Ext.form.DateField({format:'Y年m月d日'})));
  233.             }
  234.         },
  235.         cellclick: function(grid, rowIndex, columnIndex, e){
  236.             if (columnIndex!=3&&columnIndex!=4) return;
  237.             var record = grid.getStore().getAt(rowIndex);  // Get the Record
  238.             var dataType = findRecordValue(fieldsDef,'value',record.get('fieldname'),'type');
  239.             if (dataType=='') return;//未选定字段,退出
  240.             if (columnIndex==3){//绑定运算符
  241.                 var grdEditor = grid.colModel.getCellEditor(columnIndex,rowIndex);
  242.                 if (grdEditor) grdEditor.destroy();
  243.                 var _store;
  244.                 switch(dataType){
  245.                     case 'string': _store = stringOp; break;
  246.                     case 'date': _store = datetimeOp; break;
  247.                     case 'boolean': _store = booleanOp; break;
  248.                     case 'int':
  249.                     case 'float': _store = numericOp; break;
  250.                     case 'lookup': _store = lookupOp; break;
  251.                 }
  252.                 grdEditor = new Ext.form.ComboBox({
  253.                     store: _store,
  254.                     mode: 'local',
  255.                     triggerAction: 'all',
  256.                     valueField: 'value',
  257.                     displayField: 'text',
  258.                     editable: false
  259.                 })
  260.                 grid.colModel.setEditor(columnIndex, new Ext.grid.GridEditor(grdEditor));
  261.             }
  262.             else if (columnIndex==4){//绑定编辑器
  263.                 var operator = record.get('operator');
  264.                 if (operator=='is null'||operator=='is not null'){
  265.                     grid.colModel.setEditor(columnIndex, null);
  266.                     return;
  267.                 }
  268.                 var grdEditor;
  269.                 switch(dataType){
  270.                     case 'string': grdEditor = objGridTextEditor; break;
  271.                     case 'date': grdEditor = objGridDateEditor; break;
  272.                     case 'boolean': grdEditor = objGridBooleanEditor; break;
  273.                     case 'int': grdEditor = objGridIntegerEditor; break;
  274.                     case 'float': grdEditor = objGridFloatEditor; break;
  275.                     case 'lookup': 
  276.                         if (objGridLookupEditor) objGridLookupEditor.destroy();
  277.                         objGridLookupEditor = new Ext.grid.GridEditor(new Ext.form.ComboBox({
  278.                             store: findRecordValue(fieldsDef,'value',record.get('fieldname'),'data'),
  279.                             mode: 'local',
  280.                             readOnly: true,
  281.                             triggerAction: 'all',
  282.                             allowBlank: false,
  283.                             editable: false,
  284.                             forceSelection: true,
  285.                             blankText:'请选择...'
  286.                         }));
  287.                         grdEditor = objGridLookupEditor;
  288.                         break;
  289.                 }
  290.                 if (grid.colModel.getCellEditor(columnIndex,rowIndex)!=grdEditor){
  291.                     grid.colModel.setEditor(columnIndex, grdEditor);
  292.                 }
  293.             }
  294.         }
  295.     }
  296. });
  297. function checkFilter(grid){
  298.     var n = grid.store.getCount();
  299.     var leftPLen = 0;
  300.     var rightPLen = 0;
  301.     for (var i=0; i<n; i++){
  302.         var record = grid.store.getAt(i);
  303.         if (record.get('fieldname')==''){
  304.             grid.getSelectionModel().selectRow(i);
  305.             Ext.Msg.alert("错误", "请选择查询字段。");
  306.             return false;
  307.         }
  308.         leftPLen += record.get('leftParenthesis').length;
  309.         rightPLen += record.get('rightParenthesis').length;
  310.         switch(record.get('operator')){
  311.             case "like '|%'":
  312.             case "like '%|'":
  313.             case "like '%|%'":
  314.             case "not like '%|%'":
  315.                 if (record.get('value')==''){
  316.                     grid.getSelectionModel().selectRow(i);
  317.                     Ext.Msg.alert("错误", "请输入内容。");
  318.                     return false;
  319.                 }
  320.             case '=':
  321.             case '<>':
  322.             case '<':
  323.             case '>':
  324.             case '<=':
  325.             case '>=':
  326.                 var dataType = findRecordValue(fieldsDef,'value',record.get('fieldname'),'type');
  327.                 if ((dataType=='lookup'||dataType=='date')&&record.get('value')==''){
  328.                     grid.getSelectionModel().selectRow(i);
  329.                     Ext.Msg.alert("错误", "请输入内容。");
  330.                     return false;
  331.                 }
  332.         }
  333.     }
  334.     if (leftPLen!=rightPLen){
  335.         Ext.Msg.alert("错误", "左括号与右括号数量不匹配,请检查。");
  336.         return false;
  337.     }
  338.     return true;
  339. }
  340. function getFilter(grid){
  341.     if (!checkFilter(grid)) return "";
  342.     var s = [];
  343.     var n = grid.store.getCount();
  344.     for (var i=0; i<n; i++){
  345.         var record = grid.store.getAt(i);
  346.         if (i>0) s.push(record.get('relation'));
  347.         s.push(record.get('leftParenthesis'));
  348.         s.push(record.get('fieldname'));
  349.         var operator = record.get('operator');
  350.         switch(operator){
  351.             case "like '|%'":
  352.             case "like '%|'":
  353.             case "like '%|%'":
  354.             case "not like '%|%'":
  355.                 s.push(operator.replace(//|/g, record.get('value').replace(//'/g,"''").replace(//%/g,"!%")));//for sql server
  356.                 break;
  357.             case "is null":
  358.             case "is not null":
  359.                 s.push(operator);
  360.                 break;
  361.             default:
  362.                 s.push(operator);
  363.                 var dataType = findRecordValue(fieldsDef,'value',record.get('fieldname'),'type');
  364.                 switch(dataType){
  365.                     case 'lookup':
  366.                         var d = findRecordValue(fieldsDef,'value',record.get('fieldname'),'data');
  367.                         if (typeof d[0][0] !='string'){
  368.                             s.push(record.get('value'));
  369.                             break;
  370.                         }
  371.                     case 'string':
  372.                         s.push("'" + record.get('value').replace(//'/g,"''") + "'");
  373.                         break;
  374.                     case 'date':
  375.                         s.push("'" + record.get('value').dateFormat('Y-m-d') + "'");
  376.                         break;
  377.                     case 'boolean':
  378.                         s.push(record.get('value')?"1":"0");//for sql server
  379.                         break;
  380.                     default:
  381.                         s.push(record.get('value'));
  382.                         break;
  383.                 }
  384.                 break;
  385.         }
  386.         s.push(record.get('rightParenthesis'));
  387.     }
  388.     return s.join(' ');   
  389. }
  390. function getFilterText(grid){
  391.     if (!checkFilter(grid)) return "";
  392.     var s = [];
  393.     var n = grid.store.getCount();
  394.     for (var i=0; i<n; i++){
  395.         var record = grid.store.getAt(i);
  396.         if (i>0) s.push(record.get('relation')=='and'?'并且':'或者');
  397.         s.push(record.get('leftParenthesis'));
  398.         s.push(findRecordValue(fieldsDef,'value',record.get('fieldname'),'text'));
  399.         var operator = record.get('operator');
  400.         switch(operator){
  401.             case "like '|%'":
  402.                 s.push("以");
  403.                 s.push('"' + record.get('value') + '"');
  404.                 s.push("开头");
  405.                 break;
  406.             case "like '%|'":
  407.                 s.push("以");
  408.                 s.push('"' + record.get('value') + '"');
  409.                 s.push("结尾");
  410.                 break;
  411.             case "like '%|%'":
  412.                 s.push("包含字符");
  413.                 s.push('"' + record.get('value') + '"');
  414.                 break;
  415.             case "not like '%|%'":
  416.                 s.push("不包含字符");
  417.                 s.push('"' + record.get('value') + '"');
  418.                 break;
  419.             case "is null":
  420.                 s.push("等于 空白");
  421.                 break;
  422.             case "is not null":
  423.                 s.push("等于 非空白");
  424.                 break;
  425.             default:
  426.                 s.push(operator);
  427.                 var dataType = findRecordValue(fieldsDef,'value',record.get('fieldname'),'type');
  428.                 switch(dataType){
  429.                     case 'lookup':
  430.                         var d = findRecordValue(fieldsDef,'value',record.get('fieldname'),'data');
  431.                         for (var j=0; j<d.length; j++)
  432.                             if (record.get('value')==d[j][0]){
  433.                                 s.push('"'+d[j][1]+'"');
  434.                                 break;
  435.                             }
  436.                         break;
  437.                     case 'string':
  438.                         s.push('"' + record.get('value') + '"');
  439.                         break;
  440.                     case 'date':
  441.                         s.push(record.get('value').dateFormat('Y-m-d'));
  442.                         break;
  443.                     case 'boolean':
  444.                         s.push(record.get('value')?"是":"否");
  445.                         break;
  446.                     default:
  447.                         s.push(record.get('value'));
  448.                         break;
  449.                 }
  450.                 break;
  451.         }
  452.         s.push(record.get('rightParenthesis'));
  453.     }
  454.     return s.join(' ');   
  455. }
  456. });
  457. </script>
  458. </head><body><div id="hello"></div>
  459. <textarea id=preview rows=5 cols=70></textarea>
  460. </body></html>
以后会考虑再封装成类。

你可能感兴趣的:(框架,Date,function,String,header,ExtJs)