最近项目中用到了select2来做下拉框,数据都是通过ajax从后台获取, 支持动态搜索等。
使用到的下拉框分有两种情况:
一种是直接发送ajax请求渲染列表;另一种因为查询回的数据有六万多条,导致整个页面卡顿,所以采用的是先让用户至少输入3个字以后再动态模糊查询数据。
基本的使用方法看官方文档就可以明白,但是在做模糊查询的时候遇到了一些问题,在此记录一下。
第一种情况的下拉框,先是封装了函数获取数据,并拼接了列表模版,然后设置templateSelection即可。

function getProvinceList(ele) {
var proList = '<option value="-1">--省--</option>'
$.ajax({
type:'get',
contentType:'application/json;charset=utf-8',
url: dicUrl + 'queryTwoLayerAddress',
dataType:'json',
success: function(res) {
if(status == 00) {
var resArr = res.data
for( var i = 0; i < resArr.length; i++) {
proList += '<option value = '+ resArr[i].code +'>'+ resArr[i].codeText +'</option>'
}
ele.html(proList)
}
}
})
}$('#addrProvince').select2({
language: localLang,
placeholder:'请选择省份',
templateSelection: getProvinceList($('#addrProvince'))
})

第二种做法则是按照文档里的做法,初始化select框后再发送ajax请求.

$('#bankName').select2({
minimumInputLength:3,
id: function(data) { //把[{id:1, text:"a"}] 转换成[{data.id:1, data.codeText:"a"}], 因为后台返回的数据是[{id:1, codeText:"a"}]
return data.id
},
// text: function(data) {return data.codeText}, //不生效
formatSelection: function (data) { return data.codeText }, //生效
ajax: {
type:'get',
url: function(params){
return dicUrl + 'query/bankCode/'+ params.term
},
dataType:'json',
data: function(params) { //输入的内容
return {
text:params.term,
}
},
processResults: function (data, page) {
//data = { results:[{ItemId:1,ItemText:"a"},{ItemId:2,ItemText:"b"}] };
//需要将查出来的数据转换成{id:***,text:***},否则点击下拉框的时候无法赋值
var array = data.data;
var i = 0;
while(i < array.length){
array[i]["id"] = array[i]['code'];
array[i]["text"] = array[i]['codeText'];
delete array[i]["ItemId"];
delete array[i]["ItemText"];
i++;
}
return { results: array };
},
cache: true,
},
placeholder:'请选择银行名称',
escapeMarkup: function(markup) { //提示语
return markup
},
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
function formatRepo (repo) {
if (repo.loading) {
return repo.text;
}
var markup = "<div class='select2-result-repository clearfix'>" +
"<div class='select2-result-repository__meta'>" +
"<div class='select2-result-repository__title'>" + repo.codeText + "</div>";
if (repo.description) {
markup += "<div class='select2-result-repository__description'>" + repo.description + "</div>";
}
return markup;
}
function formatRepoSelection (repo) {
return repo.text;
}
select2.js 默认的ajax.results 返回的数据结构是 [{id:1,text:"a"},{id:2,text:"b"}, ...].
select2.js
//source code
* @param options.results a function(remoteData, pageNumber, query) that converts data returned form the remote request to the format expected by Select2.
* The expected format is an object containing the following keys:
* results array of objects that will be used as choices
* more (optional) boolean indicating whether there are more results available
* Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}源码中在ajax的success函数中回调ajax.results

//source code
success: function (data) {
// TODO - replace query.page with query so users have access to term, page, etc.
// added query as third paramter to keep backwards compatibility
var results = options.results(data, query.page, query);
query.callback(results);
}
其实ajax.results是把请求回的数据在传递给query.callback之前先格式化成 [{id:a,text:"a"},{id:b,text:"b"}, ...]。

//source code
callback: this.bind(function (data) {
// ignore a response if the select2 has been closed before it was received
if (!self.opened()) return;
self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
self.postprocessResults(data, false, false);
if (data.more===true) {
more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));
window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
} else {
more.remove();
}
self.positionDropdown();
self.resultsPage = page;
self.context = data.context;
this.opts.element.trigger({ type: "select2-loaded", items: data });
})});
query.callback则处理一些逻辑,确保下拉框选项被选中时触发 .selectChoice。

//source code
selectChoice: function (choice) {
var selected = this.container.find(".select2-search-choice-focus");
if (selected.length && choice && choice[0] == selected[0]) {
} else {
if (selected.length) {
this.opts.element.trigger("choice-deselected", selected);
}
selected.removeClass("select2-search-choice-focus");
if (choice && choice.length) {
this.close();
choice.addClass("select2-search-choice-focus");
this.opts.element.trigger("choice-selected", choice);
}
}
}
因此,如果results格式错误,就会导致在执行.selectChoice的时候.select2-search-choice-focus不能被添加到DOM元素上(会导致点击选项以后,选项并不会被选中)
解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
也可以手动更改对象的属性名.
select.js是这么处理的的
1 2 3 4 5 6 7 8 9 10 11 12 |
|
所以,我们只要添加函数就可以覆盖默认的对象属性名了。
|
|
另一个遇到的问题就是语言本地化。
发现直接引入语言包并不生效,所以直接使用函数改写了提示语言。
var localLang = {
noResults: function() {
return '未找到匹配选项'
},
inputTooShort: function (args) {
var remainingChars = args.minimum - args.input.length;
var message = '请输入' + remainingChars + '个或更多文字';
return message;
},
searching: function () {
return '搜索中…';
}
}
$('#select2').select2({
language: localLang,
})
获取选中的名
var cardTypeW = $("#cardType option:checked").text();
获取选中的值
写法1
var cardTypeW = $("#cardType option:checked").val();
写法2
var cardTypeW = $("#cardType").find("option:selected").val();
---------------------
作者:联信zfq
来源:CSDN
原文:https://blog.csdn.net/zhaofuqiangmycomm/article/details/81513415
版权声明:本文为博主原创文章,转载请附上博文链接!
转载于:https://my.oschina.net/u/3358860/blog/3011093