jqGrid与Struts2的结合应用(五) —— 结合Action类进行数据查询

jqGrid在Struts2和MySQL环境下的增删改查应用示例 在本章中,我们将探究jqGrid这个广泛应用于Web开发中的数据表格组件,了解其强大的数据展示能力及编辑功能。jqGrid支持通过AJAX与服务器端进行数据的CRUD(创建、读取、更新、删除)操作,提供丰富API以方便开发者实现复杂的表格交互功能。在进行前后端分离的项目时,需求分析和技术选型是至关重要的步骤。首先需要深入理解业务需求,然后根据需求来选择合适的技术栈。例如,对于一个需要频繁更新UI的项目,React可能是一个好选择。如果项目需要快速开发,Vue.js可能更合适。 阅读详情

原文地址:http://blog.youkuaiyun.com/gengv/article/details/5725172

如不能转载,请联系博主,我马上删除。

这篇主要讲的是jqGrid的查找功能。

根据官方文档的介绍,jqGrid的查找功能分四种:

  • 工具条查询;
  • 自定义查询;
  • 单条件表单查询;
  • 高级表单查询(复杂条件查询);


我个人认为这样划分比较复杂,可以基本分为两大类,即:
表单查询:包括单条件查询和高级查询(复杂条件查询);
工具条查询:包括工具条查询和自定义查询;

而这两大类中,也以表单查询更常用。

现在逐个说明一下(我改变了官方文档的讲解顺序,我觉得自己的这个顺序,更直观,更靠近现实使用)。

 


1. 单条件表单查询

先从服务器端看起,为了配合jqGrid的查询功能,我们需要在JqGridBaseAction类中添加几个成员变量。成员变量的名字必须和jqGrid的prmNames选项中定义的参数名相对应上(具体参考本系列文章的第一篇)。

改进后的JqGridBaseAction类代码:

package cn.gengv.struts2ex.jqGrid;  
   
import java.util.ArrayList;  
import java.util.Collections;  
import java.util.List;  
   
import com.byzl.hare.dao.impl.Criterion;  
import com.byzl.hare.dao.impl.Criterion.CompareType;  
import com.opensymphony.xwork2.ActionSupport;  
   
@SuppressWarnings("serial")  
public abstract class JqGridBaseAction<T> extends ActionSupport {  
    private List<T> gridModel = Collections.emptyList();  
    private Integer rows = 0;  
    private Integer page = 0;  
    private Integer total = 0;  
    private Integer record = 0;  
    private String sord;  
    private String sidx;  
       
    // (1)添加和查询有关的成员变量search、searchField、searchString、searchOper  
    private boolean search;  
    private String searchField;  
    private String searchString;  
    private String searchOper;  
   
    public abstract int getResultSize();  
    public abstract List<T> listResults(int from, int length);  
       
    // (2)添加用于根据条件进行查询的方法   
    public abstract int getResultSize(List<Criterion> criteria);  
    public abstract List<T> listResults(List<Criterion> criteria, int from, int length);  
   
    public String refreshGridModel() {  
        try {  
            List<Criterion> criteria = Collections.emptyList();  
               
            // (3)如果search值为true,则表明是查询请求   
            if(search == true) {  
                   
                // (4)通过searchField、searchString、searchOper生成通用的查询条件  
                Criterion criterion = this.generateSearchCriterion(searchField, searchString, searchOper);  
              
                criteria = new ArrayList<Criterion>();  
                  
                if(criterion != null) {  
                    criteria.add(criterion);  
                }  
            }  
               
            int from = rows * (page - 1);  
            int length = rows;  
               
            List<T> results = Collections.emptyList();  
               
            if(!criteria.isEmpty()) {   // (5)如果criteria列表不为空,则根据条件进行查询  
                record = this.getResultSize(criteria);  
                results = this.listResults(criteria, from, length);  
                  
            } else {  
                record = this.getResultSize();  
                results = this.listResults(from, length);  
                  
            }  
               
            this.setGridModel(results);  
            total = (int) Math.ceil((double) record / (double) rows);  
            return SUCCESS;  
        } catch (Exception e) {  
            e.printStackTrace();  
            this.addActionError(e.getMessage());  
            return ERROR;  
        }  
    }  
      
    // (6)通过searchField、searchString、searchOper三个参数生成Criterion的方法  
    public Criterion generateSearchCriterion(String searchField,  
            String searchString, String searchOper) {  
        Criterion criterion = null;  
          
        // (7)如果searchField、searchString、searchOper均不为null,且searchString不为空字符串时,则创建Criterion  
        if (searchField != null && searchString != null  
                & searchString.length() > 0 && searchOper != null) {  
            if ("eq".equals(searchOper)) {  
                criterion = Criterion.getEqualCriterion(searchField,  
                        searchString, null);  
            } else if ("ne".equals(searchOper)) {  
                criterion = Criterion.getCompareCriterion(CompareType.NE,  
                        searchField, searchString, null);  
            } else if ("lt".equals(searchOper)) {  
                criterion = Criterion.getCompareCriterion(CompareType.LT,  
                        searchField, searchString, null);  
            } else if ("le".equals(searchOper)) {  
                criterion = Criterion.getCompareCriterion(CompareType.LTE,  
                        searchField, searchString, null);  
            } else if ("gt".equals(searchOper)) {  
                criterion = Criterion.getCompareCriterion(CompareType.GT,  
                        searchField, searchString, null);  
            } else if ("ge".equals(searchOper)) {  
                criterion = Criterion.getCompareCriterion(CompareType.GTE,  
                        searchField, searchString, null);  
            } else if ("bw".equals(searchOper)) {  
                criterion = Criterion.getLikeCriterion(searchField,  
                        searchString + "%", null);  
            } else if ("bn".equals(searchOper)) {  
                criterion = Criterion.getNotLikeCriterion(searchField,  
                        searchString + "%", null);  
            } else if ("ew".equals(searchOper)) {  
                criterion = Criterion.getLikeCriterion(searchField, "%"  
                        + searchString, null);  
            } else if ("en".equals(searchOper)) {  
                criterion = Criterion.getNotLikeCriterion(searchField, "%"  
                        + searchString, null);  
            } else if ("cn".equals(searchOper)) {  
                criterion = Criterion.getLikeCriterion(searchField, "%"  
                        + searchString + "%", null);  
            } else if ("nc".equals(searchOper)) {  
                criterion = Criterion.getNotLikeCriterion(searchField, "%"  
                        + searchString + "%", null);  
            }  
        }  
        return criterion;  
    }  
      
    // getter和setter   
    ...  
}  


说明:
  • (1)处添加了关于查询使用到的成员变量,这些成员变量会接收从客户端jqGrid传来的参数,这些参数的名称都是由jqGrid的prmNames选项定义的;
  • (2)处添加了两个方法,用于根据条件列表,进行数据记录查询;(关于条件列表List<Criterion>稍后介绍);
  • (3)处判断成员变量search的值,如果是查询请求,jqGrid会发送search值为true的请求;
  • (4)(6)(7)通过searchField、searchString、searchOper三个参数生成Criterion的方法;以前在学习Hibernate的时候,里面就介绍过使用Criterion的方式;有的朋友对Hibernate奉若神明,但我一直对Hibernate的灵活度不太满意;不过这种将查询条件抽象出来的思路还是值得借鉴的。因此,我虽然后台使用的是Spring的JdbcTemplate,但为了抽象化Dao内的操作,我自己写了一个Criterion类(具体代码在后面)。使用这个Criterion列表来简化查询条件在各个层的传递。
  • (5)如果条件列表不为空,则调用新加入的条件查询方法。

Criterion类的代码:

package com.byzl.hare.dao.impl;  
import java.util.ArrayList;  
import java.util.Collections;  
import java.util.List;  
public class Criterion {  
    public static enum CriterionType {  
        EQUAL, LIKE, COMPARE, NOT_LIKE  
    }  
    public static enum CompareType {  
        GT, GTE, LT, LTE, EQ, NE  
    }  
    private CriterionType criterionType;  
    private String tableName;  
    private String field;  
    private Object value;  
    // 将Criteria转换为SQL条件语句   
    public static String convertToSql(List<Criterion> criteria) {  
        String criteriaString = "";  
        StringBuilder sb = new StringBuilder();  
        for (Criterion criterion : criteria) {  
            String prefix = criterion.getFieldPrefix();  
            switch (criterion.getCriterionType()) {  
            case EQUAL:  
                sb.append(prefix + criterion.getField() + "=? and ");  
                break;  
            case LIKE:  
                sb.append(prefix + criterion.getField() + " like ? and ");  
                break;  
                  
            case NOT_LIKE:  
                sb.append(prefix + criterion.getField() + " not like ? and ");  
                break;  
            case COMPARE:  
                CompareType compareType = ((CompareCriterion) criterion)  
                        .getCompareType();  
                switch (compareType) {  
                case EQ:  
                    sb.append(prefix + criterion.getField() + "=? and ");  
                    break;  
                case NE:  
                    sb.append(prefix + criterion.getField() + "<>? and ");  
                    break;  
                case GT:  
                    sb.append(prefix + criterion.getField() + ">? and ");  
                    break;  
                case GTE:  
                    sb.append(prefix + criterion.getField() + ">=? and ");  
                    break;  
                case LT:  
                    sb.append(prefix + criterion.getField() + "<? and ");  
                    break;  
                case LTE:  
                    sb.append(prefix + criterion.getField() + "<=? and ");  
                    break;  
                }  
                break;  
            }  
        }  
        int i = -1;  
        if ((i = sb.lastIndexOf(" and ")) != -1) {  
            criteriaString = sb.substring(0, i);  
        }  
        return criteriaString;  
    }  
    // 将Criteria各条件的值转换为List<Object>   
    public static List<Object> getCriteriaValues(List<Criterion> criteria) {  
        List<Object> criteriaValues = criteria.isEmpty() ? Collections  
                .emptyList() : new ArrayList<Object>();  
        for (Criterion criterion : criteria) {  
            criteriaValues.add(criterion.getValue());  
        }  
        return criteriaValues;  
    }  
    public CriterionType getCriterionType() {  
        return criterionType;  
    }  
    public void setCriterionType(CriterionType criterionType) {  
        this.criterionType = criterionType;  
    }  
    public String getField() {  
        return field;  
    }  
    public void setField(String field) {  
        this.field = field;  
    }  
    public Object getValue() {  
        return value;  
    }  
    public void setValue(Object value) {  
        this.value = value;  
    }  
    public static Criterion getCompareCriterion(CompareType compareType,  
            String field, Object value, String tableName) {  
        CompareCriterion compareCriterion = new CompareCriterion();  
        compareCriterion.setCriterionType(CriterionType.COMPARE);  
        compareCriterion.setCompareType(compareType);  
        compareCriterion.setField(field);  
        compareCriterion.setValue(value);  
        compareCriterion.setTableName(tableName);  
        return compareCriterion;  
    }  
    public static Criterion getLikeCriterion(String field, Object value,  
            String tableName) {  
        LikeCriterion likeCriterion = new LikeCriterion();  
        likeCriterion.setCriterionType(CriterionType.LIKE);  
        likeCriterion.setField(field);  
        likeCriterion.setValue(value);  
        likeCriterion.setTableName(tableName);  
        return likeCriterion;  
    }  
      
    public static Criterion getNotLikeCriterion(String field, Object value,  
            String tableName) {  
        NotLikeCriterion notLikeCriterion = new NotLikeCriterion();  
        notLikeCriterion.setCriterionType(CriterionType.NOT_LIKE);  
        notLikeCriterion.setField(field);  
        notLikeCriterion.setValue(value);  
        notLikeCriterion.setTableName(tableName);  
        return notLikeCriterion;  
    }  
    public static Criterion getEqualCriterion(String field, Object value,  
            String tableName) {  
        EqualCriterion equalCriterion = new EqualCriterion();  
        equalCriterion.setCriterionType(CriterionType.EQUAL);  
        equalCriterion.setField(field);  
        equalCriterion.setValue(value);  
        equalCriterion.setTableName(tableName);  
        return equalCriterion;  
    }  
    public static class LikeCriterion extends Criterion {  
    }  
      
    public static class NotLikeCriterion extends Criterion {  
    }  
    public static class EqualCriterion extends Criterion {  
    }  
    public static class CompareCriterion extends Criterion {  
        private CompareType compareType;  
        public CompareType getCompareType() {  
            return compareType;  
        }  
        public void setCompareType(CompareType compareType) {  
            this.compareType = compareType;  
        }  
    }  
    public String getTableName() {  
        return tableName;  
    }  
    public void setTableName(String tableName) {  
        this.tableName = tableName;  
    }  
    public String getFieldPrefix() {  
        return (tableName == null || tableName.length() == 0) ? "" : tableName  
                + ".";  
    }  
}  


简要说明一下:

  • 我把Criterion分成4类:EqualCriterion、CompareCriterion、LikeCriterion、NotLikeCriterion。(具体划分方式全为使用方便)
  • 另外还有两个静态方法:convertToSql和getCriteriaValues,用来将Criterion列表转化为JdbcTemplate需要的SQL子句和参数列表。


回到ListContactsAction,代码如下:

package cn.gengv.struts2ex.jqGrid;  
   
import java.util.Collections;  
import java.util.List;  
import com.byzl.hare.dao.impl.Criterion;  
import com.byzl.hare.model.Contact;  
import com.byzl.hare.service.ContactService;  
   
@SuppressWarnings("serial")  
public class ListContactsAction extends JqGridBaseAction<Contact> {  
      
    private ContactService contactService;  
      
    @Override  
    public String execute() {  
        return this.refreshGridModel();  
    }  
      
    @Override  
    public int getResultSize() {  
        return this.contactService.queryResultsCount(null);  
    }  
    @Override  
    public List<Contact> listResults(int from, int length) {  
        return this.contactService.queryByPage(null, from, length);  
    }  
      
    @Override  
    public int getResultSize(List<Criterion> criteria) {  
        return this.contactService.queryResultsCount(criteria);  
    }  
      
    @Override  
    public List<Contact> listResults(List<Criterion> criteria, int from, int length) {  
        List<Contact> results = Collections.emptyList();  
          
        results = this.contactService.queryByPage(criteria, from, length);  
          
        return results;  
    }  
   
    public void setContactService(ContactService contactService) {  
        this.contactService = contactService;  
    }  
}  
 


OK,服务器端的工作就先这样了,应对单条件查询已经足够了。再来看看客户端需要什么特别的。

 

jqGrid的单条件查询和高级查询(复杂条件查询)都是基于表单的查询,使用的都是jqGrid的searchGrid方法:
    $("#grid_id").searchGrid( options );
或者
    $("#grid_id").jqGrid('searchGrid', options );
   
注:要想使用searchGrid方法,在下载jqGrid的时候,必须包含Common, Form Edit, Search Plugin的模块。

在Navigator按钮栏中的查询按钮,默认就是调用这个方法。

 

searchGrid也有很多选项,在language文件(grid.locale-xx.js)中,有关于这些选项的默认值定义。下面介绍一下主要常用的选项:

  • afterShowSearch :用于定义每次查询对话框显示之后,要执行的事件函数;
  • beforeShowSearch :用于定义每次查询对话框显示之前,要执行的事件函数;
  • caption :查询对话框的标题;
  • closeAfterSearch :如果设为true,则每次在查询对话框中点击“查询”按钮完成查询后,对话框都会被关闭;默认为false;
  • closeAfterReset :如果设为true,则每次在查询对话框中点击“重置”按钮完成查询后,对话框都会被关闭;默认为false;
  • closeOnEscape :如果设为true,则当按ESC键的时候,对话框会被关闭;默认为false;
  • Find :查询对话框里“查询”按钮上的文本;
  • Reset :查询对话框里“重置”按钮上的文本;
  • sopt :用来设置通用的查询规则,如['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc'];如果为设置,则使用全部规则;
  • odata :用来翻译sopt中规则的对应数组;
  • onClose :当查询对话框关闭时,将要执行的事件函数。可以返回true或false;如果返回false,则查询对话框不会被关闭。
  • onInitializeSearch :当查询对话框创建时,将要执行的事件函数。
  • recreateFilter :如果设置为true,则当动态改变colModel的属性时,重建查询并解除时间绑定。
  • sField, sOper, sValue :当提交查询请求时,对应着所包含的有关于查询的参数;默认值分别是'searchField','searchOper','searchString'。

以上这些就是关于单条件查询的选项;关于复杂条件查询的选项稍后介绍。

注意:在searchGrid方法中设定这些选项,和在navGrid方法的prmSearch参数中设置这些选项(参见上一篇),作用效果是相同的。

 

即

var singleCriterionSearch = function() {  
    $("#gridTable").jqGrid("searchGrid", {  
        caption: "查找",  
        Find: "Go!",  
        closeAfterSearch: true  
    });  
};  


等同于

$("#gridTable").jqGrid("navGrid", "#gridPager", {},{},{},{},  
    {   // 与查询相关的prmSearch参数   
        caption: "查找",  
        Find: "Go!",  
        closeAfterSearch: true  
    },{});


当点击查询对话框中的“查询”按钮的时候,jqGrid会向Server提交一个请求,例如:

http://localhost:8085/Hare/jqGridTest/jqGrid05.action?search=true&nd=1278685481936&rows=15&page=1&sidx=&sord=asc&searchField=id&searchString=9000&searchOper=ge

 

 

 

2. 高级查询(复杂条件表单查询)

在上一部分已经提到了,单条件表单查询和高级查询(复杂条件表单查询)都是用的是searchGrid方法,只不过是传入的选项值有所不同而已。其中最重要的一个选项就是multipleSearch。

下面就来详细介绍在searchGrid中,与复杂条件查询相关的主要选项:

  • multipleSearch :如果设置为true,则激活复杂条件查询;默认为false。
  • groupOps :默认通常为[ { op: "AND", text: "all" }, { op: "OR", text: "any" } ],表示需要满足多重条件的方式,例如满足所有查询条件或者满足任意查询条件。
  • sFilter :对应着在复杂查询提交请求时,对应的参数名;默认为filters。

将javascript代码改为:

$("#gridTable").jqGrid("navGrid", "#gridPager", {},{},{},{},  
    {   // 与查询相关的prmSearch参数   
        caption: "查找",  
        Find: "Go!",  
        closeAfterSearch: true,  
        multipleSearch: true,  
        groupOps: [{ op: "AND", text: "全部" }]  
    },{});


或者

var complexCriteriaSearch = function() {  
    $("#gridTable").jqGrid("searchGrid", {  
        caption: "查找",  
        Find: "Go!",  
        closeAfterSearch: true,  
        multipleSearch: true,  
        groupOps: [{ op: "AND", text: "全部" }]  
    });  
}; 



 

 

除了选项上的不同以外,客户端的另一个不同之处在于,向Server端传递的参数不同。在第一部分的例子中可以看到,当单条件查询提交请求的时候,传递的参数是:
http://localhost:8085/Hare/jqGridTest/jqGrid05.action?search=true&nd=1278685481936&rows=15&page=1&sidx=&sord=asc&searchField=id&searchString=9000&searchOper=ge

 

即:

nd: 1278688214496  
page:   1  
rows:   15  
search: true  
searchField:    id  
searchOper: ge  
searchString:   9000  
sidx:     
sord:   asc 


而复杂条件的查询的参数是下面这种形式:

http://localhost:8085/Hare/jqGridTest/jqGrid05.action?search=true&nd=1278688110637&rows=15&page=1&sidx=&sord=asc&filters=%7B%22groupOp%22%3A%22AND%22%2C%22rules%22%3A%5B%7B%22field%22%3A%22id%22%2C%22op%22%3A%22le%22%2C%22data%22%3A%221500%22%7D%2C%7B%22field%22%3A%22lastName%22%2C%22op%22%3A%22bw%22%2C%22data%22%3A%22LN-3%22%7D%2C%7B%22field%22%3A%22email%22%2C%22op%22%3A%22cn%22%2C%22data%22%3A%22sy%22%7D%5D%7D

 

即:

filters:    {"groupOp":"AND","rules":[{"field":"id","op":"le","data":"1500"},{"field":"lastName","op":"bw","data":"LN-3"},{"field":"email","op":"cn","data":"sy"}]}  
nd: 1278688110637  
page:   1  
rows:   15  
search: true  
sidx:     
sord:   asc 


我们可以发现,传递的参数中除了search以外,searchField、searchOper、searchString都不见了,取而代之的是一个filters参数。filters参数查询条件以及复杂条件的匹配方式封装成了json的格式,然后传递给Server。


针对这种格式的参数,继续使用第一个例子中的JqGridBaseAction类的查询方式,显然是无法应对的。我们必须再次改进JqGridBaseAction类。而关键之处就是如何解析这个json格式的filters参数。

 

为此,我引入了json-lib库(http://json-lib.sourceforge.net/ ),其他的关于json的java库还可以访问http://www.json.org/ 。

 

在JqGridBaseAction类中添加方法generateSearchCriteriaFromFilters(),来将filters参数解析为Criterion列表。

public List<Criterion> generateSearchCriteriaFromFilters(String filters) {  
    List<Criterion> criteria = new ArrayList<Criterion>();  
      
    JSONObject jsonObject = JSONObject.fromObject(filters);  
      
    JSONArray rules = jsonObject.getJSONArray("rules");  
      
    for(Object obj : rules) {  
        JSONObject rule = (JSONObject) obj;  
          
        String field = rule.getString("field");  
        String op = rule.getString("op");  
        String data = rule.getString("data");  
          
        Criterion criterion = this.generateSearchCriterion(field, data, op);  
          
        if(criterion != null) {  
            criteria.add(criterion);  
        }  
    }  
      
    return criteria;  
}  


其余部分的代码:

package cn.gengv.struts2ex.jqGrid;  
   
import java.util.ArrayList;  
import java.util.Collections;  
import java.util.List;  
import net.sf.json.JSONArray;  
import net.sf.json.JSONObject;  
   
import com.byzl.hare.dao.impl.Criterion;  
import com.byzl.hare.dao.impl.Criterion.CompareType;  
import com.opensymphony.xwork2.ActionSupport;  
   
@SuppressWarnings("serial")  
public abstract class JqGridBaseAction<T> extends ActionSupport {  
    private List<T> gridModel = Collections.emptyList();  
    private Integer rows = 0;  
    private Integer page = 0;  
    private Integer total = 0;  
    private Integer record = 0;  
    private String sord;  
    private String sidx;  
       
    private boolean search;  
    private String searchField;  
    private String searchString;  
    private String searchOper;  
   
    public abstract int getResultSize();  
    public abstract List<T> listResults(int from, int length);  
      
    // (1)添加filters成员变量   
    private String filters;  
       
    public abstract int getResultSize(List<Criterion> criteria);  
    public abstract List<T> listResults(List<Criterion> criteria, int from, int length);  
      
    public String refreshGridModel() {  
        try {  
            List<Criterion> criteria = Collections.emptyList();  
               
            if(search == true) {  
                criteria = new ArrayList<Criterion>();  
                  
                // (2)将Filter转化为Criterion列表,并加入总的Criterion列表  
                if(filters != null && filters.length()>0) {  
                    criteria.addAll(this.generateSearchCriteriaFromFilters(filters));  
                }  
                   
                // (3)将searchField、searchString、searchOper转化为Criterion,并加入总的Criterion列表  
                Criterion criterion = this.generateSearchCriterion(searchField, searchString, searchOper);  
                if(criterion != null) {  
                    criteria.add(criterion);  
                }  
            }  
               
            int from = rows * (page - 1);  
            int length = rows;  
               
            List<T> results = Collections.emptyList();  
               
            if(!criteria.isEmpty()) {  
                record = this.getResultSize(criteria);  
                results = this.listResults(criteria, from, length);  
                  
            } else {  
                record = this.getResultSize();  
                results = this.listResults(from, length);  
                  
            }  
               
            this.setGridModel(results);  
            total = (int) Math.ceil((double) record / (double) rows);  
            return SUCCESS;  
        } catch (Exception e) {  
            e.printStackTrace();  
            this.addActionError(e.getMessage());  
            return ERROR;  
        }  
    }  
       
       
    public Criterion generateSearchCriterion(String searchField,  
            String searchString, String searchOper) {  
        ...  
          
    }  
      
    public List<Criterion> generateSearchCriteriaFromFilters(String filters) {  
        List<Criterion> criteria = new ArrayList<Criterion>();  
          
        JSONObject jsonObject = JSONObject.fromObject(filters);  
          
        JSONArray rules = jsonObject.getJSONArray("rules");  
          
        for(Object obj : rules) {  
            JSONObject rule = (JSONObject) obj;  
              
            String field = rule.getString("field");  
            String op = rule.getString("op");  
            String data = rule.getString("data");  
              
            Criterion criterion = this.generateSearchCriterion(field, data, op);  
              
            if(criterion != null) {  
                criteria.add(criterion);  
            }  
        }  
          
        return criteria;  
    }  
    //getter和setter   
    ...  
}  
 


经过如上修改,JqGridBaseAction类可以接受单条件查询和复杂条件查询请求了。


 


3. 工具条查询

再来看看工具条查询,工具条查询主要依靠jqGrid的filterToolbar方法:
    $("#grid_id").filterToolbar(options);
或者
    $("#grid_id").jqGrid('filterToolbar',options);

 



主要的选项包括:

  • autosearch :当在查询工具条的输入框中点击回车,或者select选择框中的值发生改变的时候,search参数将设为true,并触发ajax请求。默认为true。
  • beforeSearch :查询前触发的事件函数。如果返回true,则不继续出发查询;在这种情况中,可以自己构建查询参数来查询数据。其他返回类型,都会触发查询。
  • afterSearch :查询后触发的事件函数。
  • beforeClear :当清理输入值之前触发的事件函数(例如clearToolbar方法(稍后介绍))。如果设为true,则不继续触发清理查询事件;这种情况下,可以自己构建参数来从Server获得数据。其他返回类型,都会触发事件。
  • afterClear :当清理输入值之后触发的事件函数(例如clearToolbar方法(稍后介绍))。
  • searchOnEnter :如果设为true,就参考autosearch;如果设为false,则输入字符后,立即进行查询。
  • stringResult :决定如何发送查询参数,如果设为false,则按key:value对的形式,发送参数;如果设为true,则按照复杂条件查询的方式,发送查询参数(其中包含json格式的filters参数)。
  • groupOp :只有stringResult为true时,此选项才有效;其值可以为AND或OR;默认为AND。

注:sopt选项在此方法中不会起作用。

 

在stringResult不为true的情况下,查询参数是这样的:

firstName:  FN-cjxxxds3  
lastName:   LN-3iviu7o  
nd: 1278692114137  
page:   1  
rows:   15  
search: true  
sidx:     
sord:   asc  
telNo:  TEL-gzbn1w 


而当stringResult设为true的情况下,查询参数会按照复杂条件查询的方式发送:

filters:    {"groupOp":"AND","rules":[{"field":"lastName","op":"bw","data":"LN-3iviu7o"},{"field":"firstName","op":"bw","data":"FN-cjxxxds3"},{"field":"telNo","op":"bw","data":"TEL-gzbn1w"}]}  
nd: 1278692302168  
page:   1  
rows:   15  
search: true  
sidx:     
sord:   asc 


工具条查询相关的附加方法:

  • triggerToolbar :当调用此方法,search参数会变为true,并向Server提交ajax请求;
  • clearToolbar :当调用此方法,清除输入值,并将search参数设为false,向Server提交ajax请求;
  • toggleToolbar :打开/关闭查询工具条。

注意以上三种附加方法的调用方式为:
$("#gridTable")[0].triggerToolbar();

注:一定不能少了“[0]”。

 


 

4. 自定义查询

虽然官方文档里将这种查询方式成为自定义查询,但其实就是工具条查询的变种。无非是改变了查询工具条的位置以及构建方式。

首先需要在html页面中建立一个区域,用于存放输入查询条件的表单,例如:
<div id="mysearch"></div>

然后构建查询工具条:
    $("#mysearch").filterGrid('#grid_id',options);
或者
    $("#mysearch").jqGrid('filterGrid','#grid_id',options);
   
主要选项:

  • gridModel :默认为false;如果设为true,则使用colModel中的name、index、edittype、editoptions、search等属性来构建查询(只有colModel的search属性为true的列会被用来构建查询表单);如果此项被设为false,则应构建一个filterModel数组来处理查询。
  • gridNames :默认为false;仅当gridModel为true的时候有效,当此项设为true时,会从jqGrid的colNames选项或得每列的标题。
  • filterModel :当gridModel为false是应该使用该属性构建查询表单。(稍后介绍)
  • formtype :定义查询表单应该是横向排列的还是纵向排列的。
  • autosearch :设为true时,当输入框中回车或select选择框值改变时,触发查询;设为false时,通过按钮触发查询。默认为true。
  • formclass/tableclass/buttonclass:应用于表单的样式。


其他选项,可在真正使用时,查询文档。

filterModel: [
…
{label:'LableFild', name: 'colname', stype: 'select', defval: 'default_value', surl: 'someurl', sopt:{optins for the select}},
…
]

注:由于传递查询参数的方式与工具条查询在stringResult不为true的情况下类似,即key:value对的格式,因此这种查询方式对于JqGridBaseAction类来说用处不大。

附加方法:

  • triggerSearch :触发查询;
  • clearSearch :清除查询表单中的值,并使用空表单或默认值从Server获得数据。

var sg = jQuery("#mysearch").filterGrid(...)[0];
sg.triggerSearch();
sg.clearSearch();
sg.triggerSearch();


jqGrid_JS_5.2.1 实现可编辑表格功能,全面兼容各种浏览器,与jquery完善结合,排序、宽度拖动、锁定列、翻页等很多功能,可form编辑,行编辑,单元格编辑,强大查询支持,与后台完美结合,加载速度快,json支持等等 立即下载

相关推荐

开源分享:苹果群控手机源代码解析与实战

本文介绍了苹果设备群控的基本原理和实现方法,重点解析了基于Python+Appium的群控系统构建。主要内容包括:1)设备连接管理技术(USB/Wi-Fi);2)自动化控制方式(WDA/AppleScript/Appium);3)实战演示了通过Python脚本实现多设备同时控制,涵盖环境配置、代码解析和功能说明;4)提出了多线程、图像识别等优化方向。文章为开发者提供了快速上手的群控方案,适用于自动化测试、批量管理等场景,并推荐了相关开源项目参考。

2403_88540309的博客 1344

jqgrid 查询中文字段后台返回乱码的解决办法

jqgrid 查询中文字段后台返回乱码的解决办法: 在tomcat的server.xml里的对应端口(我这是在默认的8080后添加) 添加 useBodyEncodingForURI="true" 表示tomcat用页面的编码去处理post. 修改后即为: ...

bbrruucc的博客 669

STM32F407ZGT6最小系统:从原理图到PCB的实战设计与避坑指南

本文详细介绍了STM32F407ZGT6最小系统的设计与实现,从原理图到PCB布局的完整流程。重点解析了电源、时钟、复位和调试接口等核心模块的设计要点,提供了实用的PCB布局技巧和常见问题解决方案,帮助开发者避开设计陷阱,快速完成稳定可靠的STM32F407ZGT6最小系统设计。

weixin_30955617的博客 196

jqxGrid请求异常处理

function initOurDefData(){     window.missionType = getQueryParam("missionType");     var url = "";//请求地址     var source =          {              dataType: "json",              type: "post",

hanhh的专栏 1126

Windows安装WSL子系统及docker,以及WSL和docker配置、使用及问题解决

在Windows操作系统中,Ubuntu子系统(也称为Windows Subsystem for Linux, WSL)为开发者提供了一个在Windows环境下运行Linux环境的平台。然而,有时用户在按照Ubuntu子系统或者使用WSL时,可能会遇到各种问题,下面总结一下解决方式。想要在Windows上安装Docker(实际上是基于Hyper-V或者WSL2这两项虚拟化技术),需要开启虚拟化功能,所以不管是对于系统还是硬件都有一定的要求。

sym的博客 9781

深入剖析:NAND Flash与SD NAND(贴片式SD卡)存储扇区分配表架构差异与优化策略

本文深入探讨了NAND Flash与SD NAND(贴片式SD卡)在存储技术中的架构差异及其优化策略。NAND Flash作为非易失性存储器,依赖主控芯片进行坏块管理和磨损均衡,而SD NAND则通过内置控制器和标准文件系统(如FAT)简化了存储管理。两者在写入性能、容量扩展和可靠性方面各有优劣,NAND Flash需通过磨损均衡和写入合并优化性能,而SD NAND则通过高容量和高速传输提升效率。文章为嵌入式系统开发者和硬件工程师提供了关于如何根据需求选择并优化存储介质的参考。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1237

jqGrid处理http错误和服务器端错误

我们知道,jqGrid从服务器端获取数据时,用的是ajax请求,如果请求过程中发生http错误(如后台服务器超时未响应、该url404)或者服务器端方法发生异常或错误,默认设置下的jqGrid是不会有任何提示信息的,并且也不会显示任何数据,连浏览器的javascript错都没有。 这对我们开发人员和用户都会造成疑惑,难以快速定位错误原因。 其实对jqGrid做一下设置即可让错误显示给前台。 ...

conanca的专栏 1276

AI 体验走查 - 火山引擎存储的 AI UX 探索之路

火山引擎存储技术团队驱动 AI 自主完成用户体验走查 / 可用性测试的执行与评价,帮助业务改善交互体验。 立项“故事走查”的背景诉求和 AI 机遇 如何搭建“AI 评价”能力,精准识别交互问题 让交互体验故事走查变为技术产品,讲解系统设计,包括流程、User Story 维护、框架和 AI 模型选型、Midscene.js 的集成技巧等

bytedanceospo的博客 2833

jqGrid 将行变成超连接时浏览器解析超连接错误

1、将行变成超连接如下所示 name: "CurrentScore", index: "CurrentScore", width: 80, align: "center", formatter: function (cellValue, options, rowdata, action) { ...

weixin_30273175的博客 129

RDMA学习笔记-IB五层网络协议和报文结构

Reference InfiniBand Architecture Specification Volume 1, Release 1.3 文章目录IBA 网络协议分层1.链路层1.1 LRH1.2 ICRC1.3 VCRC2.网络层(GRH)3.传输层3.1 BTH3.2 extended transport header4. 报文结构4.1 send request4.2 RDMA Write request4.3 RDMA Read request4.4 ACK4.5 Atomic operatio

u014114310的博客 9466

MATLAB 基于深度学习的步态识别算法仿真

步态识别是一种通过分析人体行走方式来识别身份的技术。基于深度学习的步态识别算法利用卷积神经网络 (CNN) 提取步态特征,并通过分类器进行身份识别。基于深度学习的步态识别算法是实现身份识别的重要手段,具有广泛的应用前景。MATLAB 提供了丰富的工具和函数,可以方便地进行算法仿真和性能评估。

走向CTO的路上... 518

【转】jqGrid与Struts2的结合应用(五) —— 结合Action类进行数据查询

转至:http://blog.youkuaiyun.com/gengv/article/details/5725172 作者:gengv   这篇主要讲的是jqGrid的查找功能。根据官方文档的介绍,jqGrid的查找功能分四种: 工具条查询; 自定义查询; 单条件表单查询; 高级表单查询(复杂条件查询); 我个人认为这样划分比较复杂,可以基本分为两大类,即:表单查询:包括单条件查询...

sobigring的博客 373

基于YOLOv11的工业装配完整性智能检测系统

在现代工业生产中,产品质量控制是确保企业竞争力的关键环节。其中,装配完整性检查——即检测产品是否安装了所有应有的部件,是质量检测中的重要一环。传统的人工检测方法存在效率低、易疲劳、主观性强等问题。本文提出了一种基于深度学习的目标检测算法YOLOv11的工业装配完整性智能检测系统,通过计算机视觉技术自动识别和验证产品装配的完整性。本文将详细阐述从数据准备、模型训练到系统部署的完整流程,提供可执行的代码实现,并介绍一个适用于该任务的参考数据集。

YOLO 551

jqGrid与Struts2的结合应用(五) ------ 结合Action类进行数据查询 .

这篇主要讲的是jqGrid的查找功能。 根据官方文档的介绍,jqGrid的查找功能分四种: 工具条查询;自定义查询;单条件表单查询;高级表单查询(复杂条件查询); 我个人认为这样划分比较复杂,可以基本分为两大类,即: 表单查询:包括单条件查询和高级查询(复杂条件查询); 工具条查询:包括工具条查询和自定义查询; 而这两大类中,也以表单查询更常用。 现在逐个说明一下

nusoftyu的专栏 735

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

jqGrid与Struts2的结合应用(三) —— 使用自定义表单对话框编辑Grid数据

上一篇中的最后一点提到了,如果在服务器端出现异常,没能完成预期的操作,那么客户端(浏览器)中的jqGrid还继续更新数据吗? 这一篇就来说说服务器端的操作。 首先看一下服务器端的代码,我将查看行数据和操作行数据放在了两个Action类里面:ViewContactAction和ContactConsoleAction。package cn.gengv.struts2ex.jqGrid; import java.util.List; import com.byzl.hare.model.Cont

GengV - 在Java的世界流浪 2万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

jQuery学习笔记--jqGrid与Struts2集成 讲解

因为公司项目需要,在Hibernate+Struts2的环境下,研究了一下如何使用jqGrid。 说实在的,Struts2+jqGrid不是一个很好的组合。因为jqGrid中很多功能,基本上都使用的是AJAX的访问方式,并且,大家都知道,jqGrid需要的数据,要么是XML格式的,要么是JSON格式。(当然,我说的是一般情况,其实jqGrid还支持本地数据,以及xml字符串、json字符串之类的

Hurry的专栏 3046

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

JqGrid与struts2第一个实例

JqGrid与struts2第一个实例 3. 第一个实例 3.1 服务器端 用于提供数据的Action。为了可以复用这种专门接受jqGrid传来参数的Action,我抽象出一个基本类。具体代码如下:view plaincopy to clipboardprint?package cn.gengv.struts2ex.jqGrid;import java.util.Collections;...

weixin_30457881的博客 150

jqGrid与Struts2的结合应用(八) —— 奇妙的subGrid子表格

jqGrid的一项高级功能就是嵌套子表格,使用起来也非常简单。使用的方式有两种:使用普通的subGrid子表格;使用一个完整jqGrid作为子表格;显然第二种方式更加通用,功能更加强大,因此我主要使用第二种方式。至于第一种方式,可以具体参考官方文档(http://www.trirand.com/jqgridwiki/doku.php?id=wiki:subgrid )。 使用完整jqGrid作为子表格 使用子表格,涉及到jqGrid的三个选项:subGrid :首先必须将jqGrid的subGrid

GengV - 在Java的世界流浪 1万+

Jqgrid入门-结合Struts2+json实现数据展示(五)

DEMO用的是ssh框架实现的,具体怎么搭建的就不多做说明了。分页表格的数据操作难点就是数据展现。至于增删改直接用hibernate原生的方法实现即可。 初步分析:表格要实现分页,那么一页显示多少条数(PageSize)和当前页码(CurrentPage)这两个条件必不可少。为了实现点击任何一列的表头进行排序,那么排序的列名(Sidx)和排序规则(Sort)必不可少。有...

aichuxia4449的博客 171
上一篇: jqGrid与Struts2的结合应用(四) —— 丰富多彩的Pager Bar
下一篇: jqGrid与Struts2的结合应用(六) —— 使用colModel设置查询功能
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值