首页 web前端 js教程 jQuery插件select2利用ajax高效查询大数据列表

jQuery插件select2利用ajax高效查询大数据列表

Jan 11, 2018 pm 02:33 PM
ajax jquery

select2是一款jQuery插件,是普通form表单select组件的升级版。本文主要和大家介绍jQuery插件select2利用ajax高效查询大数据列表(可搜索、可分页),需要的的朋友参考下吧,希望能帮助到大家。

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

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

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

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

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

demo效果
demo检索结果
下拉刷新

本地实战结果

本地实战结果

二、导入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 = "<p class=&#39;select2-result-repository clearfix&#39;>" + "<p class=&#39;select2-result-repository__avatar&#39;><img src=&#39;"
       + repo.headimgUrl + "&#39; /></p>" + "<p class=&#39;select2-result-repository__meta&#39;>"
       + "<p class=&#39;select2-result-repository__title&#39;>" + repo.username + "</p>";
     if (repo.realname) {
      markup += "<p class=&#39;select2-result-repository__description&#39;>" + repo.realname + "</p>";
     }
     markup += "<p class=&#39;select2-result-repository__statistics&#39;>"
       + "<p class=&#39;select2-result-repository__forks&#39;><i class=&#39;fa fa-user&#39;></i> 下级会员数" + repo.children_count + " </p>"
       + "</p>" + "</p></p>";
     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 != &#39;&#39;">and m.username like CONCAT('%', '${mo.username}', '%')</if>
 <choose>
  <when test="orderField !=null and orderField !=&#39;&#39;">
   ORDER BY ${orderField}
   <if test="orderDirection != null and orderDirection != &#39;&#39;">${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 != &#39;&#39;">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
 }
},
登录后复制

相关推荐:

完美解决BootStrap模态框和select2合用时input无法获取焦点问题

完美解决BootStrap下的弹出框加载select2框架失败

jquery select2的使用心得(推荐)

以上是jQuery插件select2利用ajax高效查询大数据列表的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1670
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1274
29
C# 教程
1256
24
PHP 与 Ajax:构建一个自动完成建议引擎 PHP 与 Ajax:构建一个自动完成建议引擎 Jun 02, 2024 pm 08:39 PM

使用PHP和Ajax构建自动完成建议引擎:服务器端脚本:处理Ajax请求并返回建议(autocomplete.php)。客户端脚本:发送Ajax请求并显示建议(autocomplete.js)。实战案例:在HTML页面中包含脚本并指定search-input元素标识符。

jQuery中如何使用PUT请求方式? jQuery中如何使用PUT请求方式? Feb 28, 2024 pm 03:12 PM

jQuery中如何使用PUT请求方式?在jQuery中,发送PUT请求的方法与发送其他类型的请求类似,但需要注意一些细节和参数设置。PUT请求通常用于更新资源,例如更新数据库中的数据或更新服务器上的文件。以下是在jQuery中使用PUT请求方式的具体代码示例。首先,确保引入了jQuery库文件,然后可以通过以下方式发送PUT请求:$.ajax({u

jQuery小技巧:快速修改页面所有a标签的文本 jQuery小技巧:快速修改页面所有a标签的文本 Feb 28, 2024 pm 09:06 PM

标题:jQuery小技巧:快速修改页面所有a标签的文本在网页开发中,我们经常需要对页面中的元素进行修改和操作。在使用jQuery时,有时候需要一次性修改页面中所有a标签的文本内容,这样可以节省时间和精力。下面将介绍如何使用jQuery快速修改页面所有a标签的文本,同时给出具体的代码示例。首先,我们需要引入jQuery库文件,确保在页面中引入了以下代码:&lt

如何使用Ajax从PHP方法中获取变量? 如何使用Ajax从PHP方法中获取变量? Mar 09, 2024 pm 05:36 PM

使用Ajax从PHP方法中获取变量是Web开发中常见的场景,通过Ajax可以实现页面无需刷新即可动态获取数据。在本文中,将介绍如何使用Ajax从PHP方法中获取变量,并提供具体的代码示例。首先,我们需要编写一个PHP文件来处理Ajax请求,并返回所需的变量。下面是一个简单的PHP文件getData.php的示例代码:

使用jQuery修改所有a标签的文本内容 使用jQuery修改所有a标签的文本内容 Feb 28, 2024 pm 05:42 PM

标题:使用jQuery修改所有a标签的文本内容jQuery是一款流行的JavaScript库,被广泛用于处理DOM操作。在网页开发中,经常会遇到需要修改页面上链接标签(a标签)的文本内容的需求。本文将介绍如何使用jQuery来实现这个目标,并提供具体的代码示例。首先,我们需要在页面中引入jQuery库。在HTML文件中添加以下代码:

PHP 与 Ajax:创建动态加载内容的解决方案 PHP 与 Ajax:创建动态加载内容的解决方案 Jun 06, 2024 pm 01:12 PM

Ajax(异步JavaScript和XML)允许在不重新加载页面情况下添加动态内容。使用PHP和Ajax,您可以动态加载产品列表:HTML创建一个带有容器元素的页面,Ajax请求加载数据后将数据添加到该元素中。JavaScript使用Ajax通过XMLHttpRequest向服务器发送请求,从服务器获取JSON格式的产品数据。PHP使用MySQL从数据库查询产品数据,并将其编码为JSON格式。JavaScript解析JSON数据,并将其显示在页面容器中。点击按钮触发Ajax请求,加载产品列表。

了解jQuery中eq的作用及应用场景 了解jQuery中eq的作用及应用场景 Feb 28, 2024 pm 01:15 PM

jQuery是一种流行的JavaScript库,被广泛用于处理网页中的DOM操作和事件处理。在jQuery中,eq()方法是用来选择指定索引位置的元素的方法,具体使用方法和应用场景如下。在jQuery中,eq()方法选择指定索引位置的元素。索引位置从0开始计数,即第一个元素的索引是0,第二个元素的索引是1,依此类推。eq()方法的语法如下:$("s

PHP 与 Ajax:提高 Ajax 安全性的方法 PHP 与 Ajax:提高 Ajax 安全性的方法 Jun 01, 2024 am 09:34 AM

为了提升Ajax安全性,有几种方法:CSRF保护:生成令牌并将其发送到客户端,在请求中添加到服务器端进行验证。XSS保护:使用htmlspecialchars()过滤输入,防止恶意脚本注入。Content-Security-Policy头:限制恶意资源加载,指定允许加载脚本和样式表的来源。验证服务器端输入:验证从Ajax请求接收的输入,防止攻击者利用输入漏洞。使用安全Ajax库:利用jQuery等库提供的自动CSRF保护模块。

See all articles