溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

jQuery插件select2如何利用ajax高效查詢大數(shù)據(jù)列表

發(fā)布時間:2021-07-22 13:43:11 來源:億速云 閱讀:252 作者:小新 欄目:web開發(fā)

這篇文章將為大家詳細講解有關(guān)jQuery插件select2如何利用ajax高效查詢大數(shù)據(jù)列表,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

select2是一款jQuery插件,是普通form表單select組件的升級版。

可以定制搜索、遠程數(shù)據(jù)集(Remote data,本篇主要介紹點)、無限滾動(數(shù)據(jù)分頁功能,這一點很妙)、還有很多高端的參數(shù)設(shè)置

內(nèi)置了40種國際化語言,不過這里我們只需要用到中文。

同時支持現(xiàn)代和傳統(tǒng)瀏覽器內(nèi)置,甚至包括惹人不高興的IE8。

那么,現(xiàn)在讓我們開始一段select2的奇幻之旅吧!

一、驚艷的效果,來一睹為快吧

jQuery插件select2如何利用ajax高效查詢大數(shù)據(jù)列表
jQuery插件select2如何利用ajax高效查詢大數(shù)據(jù)列表
jQuery插件select2如何利用ajax高效查詢大數(shù)據(jù)列表

本地實戰(zhàn)結(jié)果

jQuery插件select2如何利用ajax高效查詢大數(shù)據(jù)列表

二、導(dǎo)入css和js到網(wǎng)站上

1.使用CDN,節(jié)省自己網(wǎng)站的流量

<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>
<!-- 中文國際化還需要進行參數(shù)設(shè)置 -->
<script type="text/javascript" src="${ctx}/common/select2/js/i18n/zh-CN.js"></script>

三、真刀真槍的干起來

第一步、定制頁面?zhèn)€性化元素

<select name="parentid" class="js-data-example-ajax" href="${ctx}/member/loadMembersInfo.do?uid=${mem.uid}" rel="external nofollow"  inputMessage="請輸入會員編號(可部分匹配)">
 <option selected="selected" value="666">沉默王二</option>
</select>

Java端通過name屬性可獲得select的value值。

設(shè)置class為js-data-example-ajax,頁面加載時對該組件進行select2的初始化。

href屬性為ajax提供后臺檢索的URL。

style設(shè)置組件的寬度。

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"),// 添加默認參數(shù)
    ajax : {
     url : $this.attr("href"),
     dataType : 'json',
     delay : 250,// 延遲顯示
     data : function(params) {
      return {
       username : params.term, // 搜索框內(nèi)輸入的內(nèi)容,傳遞到Java后端的parameter為username
       page : params.page,// 第幾頁,分頁哦
       rows : 10// 每頁顯示多少行
      };
     },
     // 分頁
     processResults : function(data, params) {
      params.page = params.page || 1;
      return {
       results : data.data,// 后臺返回的數(shù)據(jù)集
       pagination : {
        more : params.page < data.total// 總頁數(shù)為10,那么1-9頁的時候都可以下拉刷新
       }
      };
     },
     cache : false
    },
    escapeMarkup : function(markup) {
     return markup;
    }, // let our custom formatter work
    minimumInputLength : 1,// 最少輸入一個字符才開始檢索
    templateResult : function(repo) {// 顯示的結(jié)果集格式,這里需要自己寫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> 下級會員數(shù)" + repo.children_count + " </div>"
       + "</div>" + "</div></div>";
     return markup;
    }, 
    templateSelection : function(repo) {
     return repo.realname || repo.text;
    }// 列表中選擇某一項后顯示到文本框的內(nèi)容
   });
  });
 });
</script>

第三步、Java端接收參數(shù)并返回結(jié)果集,不用我強調(diào),這步很重要

@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);
 // 分頁參數(shù)的轉(zhuǎn)換,需要和前臺select2進行匹配,下文放代碼
 BaseConditionVO vo = getBaseConditionVOForTable(request);
 vo.addParams("username", StrUtil.getUTF8String(request.getParameter("username")));
 vo.addParams("uid", uid);
 // 封裝結(jié)果集,和前臺select2也是匹配的。
 PageGrid page = createPageGrid(this.membersMapper.getPromoterList(vo, vo.createRowBounds()), vo,
   this.membersMapper.searchPromoterTotalCount(vo));
 // 以json格式寫入到response
 out(page, response);
}

接下來,把關(guān)鍵的源碼貼出來,可能和你的項目不吻合,但可以參考。

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 : 對參數(shù)類型進行封裝.
  */
 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端分頁參數(shù)匹配

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端的數(shù)據(jù)封裝

@XStreamAlias("pageGrid")
@SuppressWarnings("rawtypes")
public class PageGrid {
 private int page;
 // 總頁數(shù),和select2的processResults.pagination匹配
 private int total;
 private int records;
 // 數(shù)據(jù)結(jié)果集,和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獲取的數(shù)據(jù)源和PageGrid進行轉(zhuǎn)換匹配

protected PageGrid createPageGrid(List list, BaseConditionVO vo, int searchTotalCount) {
 PageGrid pageGrid = new PageGrid();
 // 數(shù)據(jù)
 pageGrid.setData(list);
 // 當前頁
 pageGrid.setPage(vo.getPageNum());
 // 總數(shù)目
 pageGrid.setRecords(list.size());
 // 總頁數(shù)
 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的分頁,超簡單,只要設(shè)置了createRowBounds,mybatis就會自動為你分頁,這個就厲害了。

List getPromoterList(BaseConditionVO vo, RowBounds createRowBounds);

sql語句,這里的關(guān)鍵點是必須要回傳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,嗯,這里無須關(guān)注,這就是框架要為我們做的事情。

總數(shù)

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功能在代碼部分就完全貼出來完了。

不過,我最后還是要強調(diào)幾個點:

1.分頁的參數(shù)Java端和select2一定要對照起來。

2.回傳的數(shù)據(jù)一定要傳遞一個id回來,否則回來的列表不能選中,為什么呢?調(diào)查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恰好又是列表選中的關(guān)鍵屬性。
// 這個就是個坑,只能這么說,select2給出的api上完全不講這點,我去?。。。。。?!
 if (data.id == null) {
  delete attrs['aria-selected'];
 }
 ......
}

3.form表單如何獲取select2的值?答案是,1.返回結(jié)果集必須有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
 }
},

關(guān)于“jQuery插件select2如何利用ajax高效查詢大數(shù)據(jù)列表”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI