最近項目中用到了select2來作下拉框,數據都是經過ajax從後臺獲取, 支持動態搜索等。html
使用到的下拉框分有兩種狀況:ajax
一種是直接發送ajax請求渲染列表;另外一種由於查詢回的數據有六萬多條,致使整個頁面卡頓,因此採用的是先讓用戶至少輸入3個字之後再動態模糊查詢數據。json
基本的使用方法看官方文檔就能夠明白,可是在作模糊查詢的時候遇到了一些問題,在此記錄一下。數據結構
第一種狀況的下拉框,先是封裝了函數獲取數據,並拼接了列表模版,而後設置templateSelection便可。app
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,post
placeholder:'請選擇省份',this
templateSelection: getProvinceList($('#addrProvince'))lua
})url
第二種作法則是按照文檔裏的作法,初始化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();