jQuery插件select2利用ajax高效查询大数据列表(可搜索、可分页)

select2是一款jQuery插件,是普通form表单select组件的升级版。

可以定制搜索、远程数据集(Remote data,本篇主要介绍点)、无限滚动(数据分页功能,这一点很妙)、还有很多高端的参数设置(有需要的下次介绍)。

内置了40种国际化语言,不过这里我们只需要用到中文。

同时支持现代和传统浏览器内置,甚至包括惹人不高兴的IE8。

那么,现在让我们开始一段select2的奇幻之旅吧!

一、惊艳的效果,来一睹为快吧



本地实战结果

二、导入css和js到网站上

1.使用CDN,节省自己网站的流量

<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="external nofollow" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script> 

2.下载文件到本地,可以做一些个性的定制(比如说修改提示语)

git下载地址

<!-- select2 -->
<link rel="stylesheet" type="text/css" href="${ctx}/common/select2/css/select2.css" rel="external nofollow" />
<script type="text/javascript" src="${ctx}/common/select2/js/select2.full.js"></script>
<!-- 中文国际化还需要进行参数设置 -->
<script type="text/javascript" src="${ctx}/common/select2/js/i18n/zh-CN.js"></script>

三、真刀真枪的干起来

第一步、定制页面个性化元素

<select name="parentid" class="js-data-example-ajax" href="${ctx}/member/loadMembersInfo.do?uid=${mem.uid}" rel="external nofollow" style="width:400px" inputMessage="请输入会员编号(可部分匹配)">
 <option selected="selected" value="666">沉默王二</option>
</select>

Java端通过name属性可获得select的value值。

设置class为js-data-example-ajax,页面加载时对该组件进行select2的初始化。

href属性为ajax提供后台检索的URL。

style设置组件的宽度。

inputMessage属性定制个性化的提示语,默认的英文版为Please enter 1 or more characters,中文国际化为“请再输入至少1个字符”,都不太能满足个性化需求,所以需要改,后面介绍。
提供一个默认的option,页面没检索之前显示。

第二步、select2组件化,注释写得很详细了哦

<script type="text/javascript">
 $(function() {
  $("select.js-data-example-ajax").each(
  function() {
   var $this = $(this);
   $this.select2({
    language : "zh-CN",// 指定语言为中文,国际化才起效
    inputMessage : $this.attr("inputMessage"),// 添加默认参数
    ajax : {
     url : $this.attr("href"),
     dataType : 'json',
     delay : 250,// 延迟显示
     data : function(params) {
      return {
       username : params.term, // 搜索框内输入的内容,传递到Java后端的parameter为username
       page : params.page,// 第几页,分页哦
       rows : 10// 每页显示多少行
      };
     },
     // 分页
     processResults : function(data, params) {
      params.page = params.page || 1;
      return {
       results : data.data,// 后台返回的数据集
       pagination : {
        more : params.page < data.total// 总页数为10,那么1-9页的时候都可以下拉刷新
       }
      };
     },
     cache : false
    },
    escapeMarkup : function(markup) {
     return markup;
    }, // let our custom formatter work
    minimumInputLength : 1,// 最少输入一个字符才开始检索
    templateResult : function(repo) {// 显示的结果集格式,这里需要自己写css样式,可参照demo
     // 正在检索
     if (repo.loading)
      return repo.text;
     var markup = repo.username;
     markup += repo.realname;
     var markup = "<div class='select2-result-repository clearfix'>" + "<div class='select2-result-repository__avatar'><img src='"
       + repo.headimgUrl + "' /></div>" + "<div class='select2-result-repository__meta'>"
       + "<div class='select2-result-repository__title'>" + repo.username + "</div>";
     if (repo.realname) {
      markup += "<div class='select2-result-repository__description'>" + repo.realname + "</div>";
     }
     markup += "<div class='select2-result-repository__statistics'>"
       + "<div class='select2-result-repository__forks'><i class='fa fa-user'></i> 下级会员数" + repo.children_count + " </div>"
       + "</div>" + "</div></div>";
     return markup;
    },
    templateSelection : function(repo) {
     return repo.realname || repo.text;
    }// 列表中选择某一项后显示到文本框的内容
   });
  });
 });
</script>

第三步、Java端接收参数并返回结果集,不用我强调,这步很重要

@RequestMapping(value = "loadMembersInfo")
public void loadMembersInfo(HttpServletRequest request, HttpServletResponse response) throws IOException {
 Integer uid = StrUtil.parseStringToInt(request.getParameter("uid"));
 Members mem = this.memberService.selectByPrimaryKey(uid);
 // 分页参数的转换,需要和前台select2进行匹配,下文放代码
 BaseConditionVO vo = getBaseConditionVOForTable(request);
 vo.addParams("username", StrUtil.getUTF8String(request.getParameter("username")));
 vo.addParams("uid", uid);
 // 封装结果集,和前台select2也是匹配的。
 PageGrid page = createPageGrid(this.membersMapper.getPromoterList(vo, vo.createRowBounds()), vo,
   this.membersMapper.searchPromoterTotalCount(vo));
 // 以json格式写入到response
 out(page, response);
}

接下来,把关键的源码贴出来,可能和你的项目不吻合,但可以参考。

BaseConditionVO.Java
public class BaseConditionVO {
 public final static int PAGE_SHOW_COUNT = 50;
 private int pageNum = 1;
 private int numPerPage = 0;
 private int totalCount = 0;
 private String orderField;
 private String orderDirection;
 /**
  * @Fields ps : 对参数类型进行封装.
  */
 private Map<String, Object> mo = new HashMap<String, Object>();
 public int getPageNum() {
  return pageNum;
 }
 public void setPageNum(int pageNum) {
  this.pageNum = pageNum;
 }
 public int getNumPerPage() {
  return numPerPage > 0 ? numPerPage : PAGE_SHOW_COUNT;
 }
 public void setNumPerPage(int numPerPage) {
  this.numPerPage = numPerPage;
 }
 public String getOrderField() {
  return orderField;
 }
 public void setOrderField(String orderField) {
  this.orderField = orderField;
 }
 public String getOrderDirection() {
  return "desc".equals(orderDirection) ? "desc" : "asc";
 }
 public void setOrderDirection(String orderDirection) {
  this.orderDirection = orderDirection;
 }
 public int getTotalCount() {
  return totalCount;
 }
 public void setTotalCount(int totalCount) {
  this.totalCount = totalCount;
 }
 public int getStartIndex() {
  int pageNum = this.getPageNum() > 0 ? this.getPageNum() - 1 : 0;
  return pageNum * this.getNumPerPage();
 }
 public RowBounds createRowBounds() {
  RowBounds ro = new RowBounds(this.getStartIndex(), this.getNumPerPage());
  return ro;
 }
 /**
  * @Title: addParams
  * @Description: 添加查询条件
  * @param key
  * @param value
  */
 public void addParams(String key, Object value) {
  this.getMo().put(key, value);
 }
 /**
 * @Title: getParams
 * @Description: 获取查询条件
 * @param key
 * @return
 */
 public Object getParams(String key) {
  return this.getMo().get(key);
 }
 /**
  * @return the mo
  */
 public Map<String, Object> getMo() {
  return mo;
 }
 /**
  * @param mo
  *   the mo to set
  */
 public void setMo(Map<String, Object> mo) {
  this.mo = mo;
 }
}

selec2的分页和Java端分页参数匹配

protected BaseConditionVO getBaseConditionVOForTable(HttpServletRequest req) {
 BaseConditionVO vo = new BaseConditionVO();
 // 当前页
 int currentPage = StrUtil.parseStringToInt(req.getParameter("page"));
 // 一页显示多少行
 int sizes = StrUtil.parseStringToInt(req.getParameter("rows"));
 // 排序
 String sortOrder = StrUtil.getString(req.getParameter("sord"));
 String sortCol = StrUtil.getString(req.getParameter("sidx"));
 vo.setNumPerPage(sizes);
 vo.setPageNum(currentPage);
 vo.setOrderField(sortCol);
 vo.setOrderDirection(sortOrder);
 return vo;
}

Java端到select2端的数据封装

@XStreamAlias("pageGrid")
@SuppressWarnings("rawtypes")
public class PageGrid {
 private int page;
 // 总页数,和select2的processResults.pagination匹配
 private int total;
 private int records;
 // 数据结果集,和select2的processResults.results匹配
 private List data;
 public int getPage() {
  return this.page;
 }
 public void setPage(int page) {
  this.page = page;
 }
 public int getTotal() {
  return this.total;
 }
 public void setTotal(int total) {
  this.total = total;
 }
 public int getRecords() {
  return this.records;
 }
 public void setRecords(int records) {
  this.records = records;
 }
 public List getData() {
  return this.data;
 }
 public void setData(List data) {
  this.data = data;
 }
}

MySQL获取的数据源和PageGrid进行转换匹配

protected PageGrid createPageGrid(List list, BaseConditionVO vo, int searchTotalCount) {
 PageGrid pageGrid = new PageGrid();
 // 数据
 pageGrid.setData(list);
 // 当前页
 pageGrid.setPage(vo.getPageNum());
 // 总数目
 pageGrid.setRecords(list.size());
 // 总页数
 int total = 0;
 if (pageGrid.getRecords() != 0) {
  total = searchTotalCount % vo.getNumPerPage() == 0 ? searchTotalCount / vo.getNumPerPage()
    : searchTotalCount / vo.getNumPerPage() + 1;
 }
 pageGrid.setTotal(total);
 return pageGrid;
}

mybatis的分页,超简单,只要设置了createRowBounds,mybatis就会自动为你分页,这个就厉害了。

List getPromoterList(BaseConditionVO vo, RowBounds createRowBounds);

sql语句,这里的关键点是必须要回传id(m.uid as id)到select2.

<select id="getPromoterList" resultType="hashmap" parameterType="map">
 select
 m.uid as id,
 convert(m.username,char) username,
 m.realname,
 m.children_count,
 m.headimgUrl
 from
 members m
 where m.deleteflag=0
 <if test="mo.username != ''">and m.username like CONCAT('%', '${mo.username}', '%')</if>
 <choose>
  <when test="orderField !=null and orderField !=''">
   ORDER BY ${orderField}
   <if test="orderDirection != null and orderDirection != ''">${orderDirection}</if>
  </when>
  <otherwise>
   order by m.username DESC
  </otherwise>
 </choose>
</select>

你是不是没看见mysql的分页limit,嗯,这里无须关注,这就是框架要为我们做的事情。

总数

int searchPromoterTotalCount(BaseConditionVO vo);

count(0)就好

<select id="searchPromoterTotalCount" resultType="java.lang.Integer" parameterType="map">
 select count(0) as a
 from
 members m
 where m.deleteflag=0
 <if test="mo.username != ''">and m.username like CONCAT('%', '${mo.username}', '%')</if>
</select>

out输出到response中

protected void out(Object result, HttpServletResponse response) throws IOException {
 ServletOutputStream out = response.getOutputStream();
 ObjectMapper objectMapper = new ObjectMapper();
 objectMapper.writeValue(out, result);
 out.flush();
}

到这,select2的remote功能在代码部分就完全贴出来完了。

不过,我最后还是要强调几个点:

1.分页的参数Java端和select2一定要对照起来。

2.回传的数据一定要传递一个id回来,否则回来的列表不能选中,为什么呢?调查select2的源码可以知道。

 Results.prototype.option = function (data) {
 var option = document.createElement('li');
 option.className = 'select2-results__option';
 var attrs = {
  'role': 'treeitem',
  'aria-selected': 'false'
 };
 if (data.disabled) {
  delete attrs['aria-selected'];
  attrs['aria-disabled'] = 'true';
 }
// id为空的情况下,删除的aria-selected,而aria-selected恰好又是列表选中的关键属性。
// 这个就是个坑,只能这么说,select2给出的api上完全不讲这点,我去!!!!!!!
 if (data.id == null) {
  delete attrs['aria-selected'];
 }
 ......
}

3.form表单如何获取select2的值?答案是,1.返回结果集必须有id,2.input标签上必须要name属性。

4.如何自定义inputMessage呢?

在select2.js中找到以下代码,注意注释部分

S2.define('select2/data/minimumInputLength',[
], function () {
 function MinimumInputLength (decorated, $e, options) {
 this.minimumInputLength = options.get('minimumInputLength');
 // inputMessage
 this.inputMessage = options.get('inputMessage');
 decorated.call(this, $e, options);
 }
 MinimumInputLength.prototype.query = function (decorated, params, callback) {
 params.term = params.term || '';
 if (params.term.length < this.minimumInputLength) {
  this.trigger('results:message', {
  message: 'inputTooShort',
  args: {
   minimum: this.minimumInputLength,
   input: params.term,
   inputMessage : this.inputMessage, // inputMessage,传递给i18n
   params: params
  }
  });
  return;
 }
 decorated.call(this, params, callback);
 };
 return MinimumInputLength;
});

select2.js中defaults中增加上inputMessage

 this.defaults = {
 ...
  minimumInputLength: 0,
  inputMessage: '',
  maximumInputLength: 0,
  ...
 };

然后在zh-CN.js文件中修改inputTooShort方法

inputTooShort : function(e) {
 if (e.inputMessage) {
  return e.inputMessage;// 增加inputMessage
 } else {
  var t = e.minimum - e.input.length, n = "请再输入至少" + t + "个字符";
  return n
 }
},

以上所述是小编给大家介绍的jQuery插件select2利用ajax高效查询大数据列表(可搜索、可分页),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 使用CSS和jQuery模拟select并附提交后取得数据的代码

    模拟select 并带有提交后取得数据的代码  HTML Code 复制代码 代码如下: <div id="dropdown"> <p>请选择城市</p> <ul> <li><a href="#" rel="2">北京</a></li> <li><a href="#" rel="3">上海

  • jquery通过select列表选择框对表格数据进行过滤示例

    jquery通过select列表选择框对表格数据进行过滤 表格数据 复制代码 代码如下: <table id="example">    <thead>        <tr>            <th>Name</th>            <th>Surname</th>        </tr>    </thead>    <tbody>       

  • jquery Ajax实现Select动态添加数据

    jquery Ajax实现Select动态添加数据,具体内容如下 1.背景  最近在工作中,遇到了一个关于select的问题.一般情况下,select下拉框中的数据都是固定的或者直接在jsp中读取列表值显示.但是,这次要实现select与别的选项框联动,也就是要动态添加option数据.查阅了很多资料,终于搞定.下面就分享一下,如何利用jQuery和Ajax实现select动态添加数据. 2.本文代码实现的是车辆型号根据车辆品牌联动显示的功能.首先,是jsp中的车辆品牌定义,这个很简单.如下:

  • lyhucSelect基于Jquery的Select数据联动插件

    数据源: 复制代码 代码如下: var areaInfo = new Array(); areaInfo[0] = new Array(); areaInfo[0][0]="1"; areaInfo[0][1]="Beijing"; areaInfo[0][2]="0"; areaInfo[0][3]="0"; areaInfo[1] = new Array(); areaInfo[1][0]="2"; a

  • jQuery插件select2利用ajax高效查询大数据列表(可搜索、可分页)

    select2是一款jQuery插件,是普通form表单select组件的升级版. 可以定制搜索.远程数据集(Remote data,本篇主要介绍点).无限滚动(数据分页功能,这一点很妙).还有很多高端的参数设置(有需要的下次介绍). 内置了40种国际化语言,不过这里我们只需要用到中文. 同时支持现代和传统浏览器内置,甚至包括惹人不高兴的IE8. 那么,现在让我们开始一段select2的奇幻之旅吧! 一.惊艳的效果,来一睹为快吧 本地实战结果 二.导入css和js到网站上 1.使用CDN,节省自

  • 如何利用AJAX获取Django后端数据详解

    使用Django服务网页时,只要用户执行导致页面更改的操作,即使该更改仅影响页面的一小部分,它都会将完整的HTML模板传递给浏览器.但是如果我们只想更新页面的一部分,则不必完全重新渲染页面-这时候就要用到AJAX了. 使用AJAX获取Django后端数据插图 AJAX提供了一种将GET或POST请求发送到Django视图并接收任何返回的数据而无需刷新页面的方法.现代JavaScript包含fetch API,该API为我们提供了一种纯JavaScript方式来发送AJAX请求. 让我们看一下如何

  • Django框架利用ajax实现批量导入数据功能

    本文实例为大家分享了网页中利用ajax实现批量导入数据功能的实现方法,供大家参考,具体内容如下 url.py代码: 复制代码 代码如下: url(r'^workimport/$', 'keywork.views.import_keywork', name='import_keywork') view.py代码: from keywork.models import DevData from django.http import JsonResponse #django ajax部分 def im

  • ajax动态查询数据库数据并显示在前台的方法

    今天做了一个ajax动态查询数据库的小Demo,又重新学习了一下ajax的一些知识.在此和大家分享一下...... 啥都别说了,先上代码 Controller层 查询总用户数 @RequestMapping(value = "/findTotalUsers.do",method = RequestMethod.GET) public @ResponseBody Long findTotalUsers(){ ModelAndView modelAndView = new ModelAnd

  • 使用jquery DataTable和ajax向页面显示数据列表的方法

    首先在html页面定义好相关长度的行和列,假设table的id=data-table"" 使用jquery DataTable在js中这么写 $(function() { $('#data-table').DataTable( { order : [ [ 1, 'desc' ] ], ajax : { url : "/products", type : 'GET', dataSrc : "" }, columns : [ { data : &qu

  • Mybatis实现查询相册数据列表流程讲解

    目录 1.书写执行的SQL语句 2.在项目的根包下创建pojo.vo.AlbumListItemVO类 3.在AlbumMapper.java中添加抽象方法 4.在AlbumMapper.xml中配置SQL语句 5.在AlbumMapperTests.java中编写并执行测试 1.书写执行的SQL语句 需要执行的SQL语句大致是: SELECT xx,xx FROM pms_album ORDER BY sort DESC, id DESC 注意:如果查询结果的数量可能超过1条,在查询的SQL语

  • jQuery插件AjaxFileUpload实现ajax文件上传

    本文实例为大家分享了AjaxFileUpload实现文件上传的具体代码,供大家参考,具体内容如下 jQuery插件AjaxFileUpload用来实现ajax文件上传,该插件使用非常简单,接下来写个demo演示怎么用AjaxFileUpload插件实现文件上传. 1.引入AjaxFileUpload插件相关的js 复制代码 代码如下: <script type="text/javascript" src="<%=basePath%>resources/js/

  • 初学Jquery插件制作 在SageCRM的查询屏幕隐藏部分行的功能

    解决思路:1. 在标题处增加一个[-][+]号,供用户点击. 2. 用户收缩和展开屏幕的行为保存在Cookie里面.页面重新加载或者用户重新登录系统,仍然能记住用户的行为. 优点:1.使用Jquery插件的形式来做,容易扩展.容易实现. 2. 保存在Cookie的行为,容易实现,减少工作量,用户也能接收.如保存在数据库,则增加页面的负载. 缺点:不能每个页面使用单独行为,既是:每次用户的收缩和扩展在系统都是全局的.并且到其他计算机登录.或者清除缓存之后,就不能记住用户的操作了. 首先使用js函数

  • 利用AJAX实现无刷新数据分页

    以前在使用Asp.Net的时候用过GridView这个控件,这个控件自带分页的功能,虽然很丑,但是功能还是很强大的.这里呢,给大家展示一下更加给力的方式--利用AJAX无刷新直接从服务器获取数据分页. 一.实现过程 注意:一下的内容都是在服务器内使用的. 首先要在服务器的路径下建立几个文件,比如,page1.txt,page2.txt,page3.txt. 每个文件中放入数组,如下: 复制代码 代码如下: [{user:'blue',pass:'123'},{user:'aaa',pass:'d

  • jQuery插件uploadify实现ajax效果的图片上传

    昨天做了一天的ajax效果的图片上传,就是想让自己学的更加的精一些,所以看了很多第三方的控件,最后还是选择了uploadify这个控件,主要原因是比较容易上手. 首先我们先参考别人的资料(我自己整理了一下) 可选项 需要参数类型 参数名字 解释 (布尔型) auto 当文件被添加到队列时,自动上传. (字符串) buttonImg 浏览按钮的背景图片路径. (字符串) buttonText 默认在按钮上显示的文本. (字符串) cancelImg 取消按钮的背景图片路径. (字符串) check

随机推荐