Select2的使用
Select2是一款基於JQuery的下拉列表插件,主要用來優化select,支持單選和多選,同時也支持分組顯示、列表檢索、遠程獲取數據等眾多好用的功能
項目地址:https://select2.org/
基本使用
需要用到的JS和CSS文件位於項目代碼下的dist目錄中,需要將這個目錄中的對應文件放入你的項目里,這一步不贅述
- 引入CSS/JS文件,由於Select2是基於Jquery的,所以要先引入Jquery,這里我們都直接引入CDN的地址
<!-- 加載 Jquery -->
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!-- 加載 Select2 -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/js/select2.min.js"></script>
- 初始化Select2
<select class="form-control" id="id_select2_demo1">
<option value="">-----單選-----</option>
<option value="1">OPS-COFFEE-A</option>
<option value="2">OPS-COFFEE-B</option>
<option value="3">OPS-COFFEE-C</option>
<option value="4">OPS-COFFEE-D</option>
<option value="5">OPS-COFFEE-E</option>
<option value="6">OPS-COFFEE-F</option>
<option value="7">OPS-COFFEE-G</option>
</select>
<script>
var selectorx = $('#id_select2_demo1').select2();
</script>
- 完成以上兩步可以看到頁面效果如下
設置提示語placeholder
$('#id_select2_demo1').select2({
placeholder: '請選擇'
});
placeholder: 選擇框的提示語,需要注意,要想讓這個提示語生效,需要select的option里邊有一個value為空的option,例如上邊例子中的
<option value="">-----單選-----</option>
隱藏搜索框
與默認的select除了樣式上的區別外,最重要的是多了個搜索框,能用來搜索option項,如果你不想顯示這個搜索框,可以通過設置項minimumResultsForSearch
隱藏
var selectorx = $('#id_select2_demo1').select2({
minimumResultsForSearch: -1
});
加載本地數據
除了實例化已經存在的select之外,也可以通過設置項data
加載本地數據
var sdata = [
{id: 1, text:'OPS-COFFEE-1'},
{id: 2, text:'OPS-COFFEE-2'},
{id: 3, text:'OPS-COFFEE-3'}
]
$('#id_select2_demo2').select2({
data: sdata
});
select2能夠加載的數據格式如上,需要兩個數據屬性id
和text
,當然你也可以加載其他的額外屬性以在需要時獲取
加載遠程數據
除了加載本地數據外,也支持ajax異步去后端獲取數據,用法如下:
$('#id_select2_demo3').select2({
placeholder: 'Ajax后端獲取數據示例',
ajax: {
url: "sdata.json",
dataType: 'json',
delay: 250,
data: function (params) {
return {
search: params.term,
};
},
processResults: function (data) {
return {
results: data
};
},
cache: true
},
minimumInputLength: 2
});
delay: 250: 配置告訴select2在用戶停止輸入多少毫秒后開始查詢,合理設置可以避免頻繁向后端發送請求
search: params.term: 定義了要傳遞給后端的查詢參數,search
為發送到服務端的參數名,params.term
表示輸入框中輸入的內容,當然這里也可以添加一些自定義的參數,例如:
data: function (params) {
return {
search: params.term,
site: "https://ops-coffee.cn"
};
},
那么當你輸入OPS
時,服務端接受到的完整參數就是/sdata.json?search=OPS&site=https://ops-coffee.cn
results: data: 定義了后台返回的數據,其中data
為select2能夠識別的格式,如果后端返回的格式不是select2能夠識別的格式,例如下邊這樣
{
"state": 1,
"message":[
{"id": 0, "text":"-----單選-----"},
{"id": 1, "text":"OPS-COFFEE-1"},
{"id": 2, "text":"OPS-COFFEE-2"},
{"id": 3, "text":"OPS-COFFEE-3"}
]
}
那么你需要先將其處理成select2能夠識別的格式,這里我們就需要取出date中的message
processResults: function (data) {
return {
results: data.message
};
},
minimumInputLength: ajax異步請求通常我們會配合配置項minimumInputLength
使用,這個配置項的意思是輸入指定長度的字符后開始搜索,也就是點擊select選擇框默認不會去后台請求數據,當你輸入指定長度的字符時才會去搜索,這樣在你搜索項非常多的時候能更精確的匹配你想要的內容
如果你想點擊即顯示所有option,那么你可以將他的值設置為0
,或者不配置這個配置
同時也可以通過maximumInputLength
配置項配置輸入字符的最大長度
多選支持
select2對多選的支持也非常簡單,跟默認的select標簽一樣只需要在select標簽中添加multiple="multiple"
即可
<select class="form-control" id="id_select2_demo4" multiple="multiple">
<option value="1">OPS-COFFEE-A</option>
<option value="3">OPS-COFFEE-C</option>
<option value="4">OPS-COFFEE-D</option>
<option value="5">OPS-COFFEE-E</option>
</select>
var selectory = $('#id_select2_demo4').select2({
placeholder: '請選擇,最多選擇三個',
allowClear: true,
maximumSelectionLength:3,
});
顯示效果如下:
allowClear: 是否顯示清楚按鈕,默認false,如果設置為true
,需要同時配置placeholder
,否則可能會引起js報錯:
TypeError: Cannot read property 'id' of undefined
maximumSelectionLength: 配置最多能選擇多少項
配置說明
另外還有幾個配置上邊沒有講到的:
width: 寬度,例如100%
multiple: 是否支持多選,默認false
closeOnSelect: 是否選中后關閉選擇框,默認true
tags: 是否可以動態創建選項
disabled: 是否禁用
debug: 是否開啟debug模式
使用進階
獲取已選擇的值,無論是單選還是多選都可以用下邊的代碼來獲取選擇的option
$('#id_select2_demo4').select2('val')
獲取已選擇的對象
$("#id_select2_demo4").select2("data")
如果想要拿到已選擇option的text值,可以通過如下方法,以下代碼中的[0]
用來獲取第一個對象,對單選合適,如果是多選的話需要循環獲取
$("#id_select2_demo4").select2("data")[0].text
selected,初始化值,設置選中項
# 單選情況下val為數字,這里的selectx為
$("#id_select2_demo1").val(2).trigger("change");
# 多選情況下val為列表
$("#id_select2_demo4").val([2,3,5]).trigger("change");
清空已選擇的值,無論是單選還是多選都可以這樣清除
$("#id_select2_demo1").val(null).trigger('change');
$("#id_select2_demo4").val(null).trigger('change');
禁用select2
$("#id_select2_demo1").prop('disabled',true);;
$("#id_select2_demo4").prop('disabled',true);;
動態添加select的option
$('#add').click(function() {
var _html = '<option value="9" selected>ops-coffee.cn</option>';
$('#id_select2_demo1').append(_html).trigger('change.select2');
$('#id_select2_demo1').select2("open");
})
change.select2: 新增select數據后觸發select2更新
.select2("open"): 打開select,open
改為close
可動態關閉select,改為destroy
可銷毀select2,恢復select默認樣式
實現下拉框中顯示圖片
一、固定方式:
html代碼:
<body style="margin-left:2%">
<div>
<h2><label>固定方式獲取</label></h2>
<p>
<label>單選:</label>
<select class="form-control" style="width: 50%" id="sel_1">
<option value="root">ROOT</option>
<option value="aojiancc">傲劍</option>
<option value="huangleicc">黃磊</option>
</select>
</p>
<p>
<label>分組多選:</label>
<select class="form-control" style="width: 50%" multiple="multiple" id="sel_2">
<optgroup label="管理員">
<option value="root">ROOT</option>
</optgroup>
<optgroup label="用戶">
<option value="aojiancc">傲劍</option>
<option value="huangleicc">黃磊</option>
</optgroup>
</select>
</p>
<p>
<label>圖文結合:</label>
<select class="js-example-templating js-states form-control" style="width: 50%" multiple="multiple" id="sel_3">
<optgroup label="管理員">
<option value="root">ROOT</option>
</optgroup>
<optgroup label="用戶">
<option value="aojiancc">傲劍</option>
<option value="huangleicc">黃磊</option>
</optgroup>
</select>
</p>
</div>
</body>
JS代碼:
<script>
//單選
$(document).ready(function () {
$('#sel_1').select2();
//設置最多能夠選擇的個數
$("#sel_2").select2({
tags: true,
placeholder: '請選擇',
maximumSelectionLength: 2 //最多能夠選擇的個數
});
//帶圖片
$("#sel_3").select2({
placeholder: '請選擇',
templateResult: formatStateResult,//選擇時
templateSelection: formatStateSelection//選擇后
});
});
//填充圖片
function formatStateResult(state) {
if (!state.id) { return state.text; }
var $state = $(
'<span><img src="/img/a5.jpg" style="width: 5%;height:5%" class="img-flag" /> ' + state.text + '</span>'
);
return $state;
};
function formatStateSelection(state) {
if (!state.id) { return state.text; }
var $state = $(
'<span><img src="/img/a5.jpg" style="width: 10%;height:10%" class="img-flag" /> ' + state.text + '</span>'
);
return $state;
};
</script>
效果:
單選:
二、ajax獲取方式(以最復雜的分頁多選且顯示圖片為例):
html代碼:
<body style="margin-left:2%">
<div>
<h2><label>遠程方式獲取</label></h2>
<p>
<label>圖文結合:</label>
<select class="js-example-data-ajax js-states form-control" style="width: 50%" multiple="multiple" id="sel_4">
<option></option>
</select>
</p>
</div>
</body>
JS代碼:
<script>
$(document).ready(function () {
$("#sel_4").select2({
ajax: {
url: '/ExportExcel/GetPageListJson',
dataType: 'json',
delay: 1000,// 搜索延遲顯示
//data:參數
data: function (params) {
return {
LikeVar: params.term, // 搜索框值
page: params.page || 1,//分頁,當前頁
rows: 2//每頁容量
};
},
//數據集處理
processResults: function (data, params) {
params.page = params.page || 1;
return {
//這里是返回的數據:數據格式必須遵循select2格式 如:{ id: 1, text: 'aojian' }, { id: 2, text: 'dahuang' }];
results: data.rows,
pagination: {
//more:表示下拉刷新,data.total表示總頁數,這里的意思是當前頁小於總頁數的時候就顯示下拉分頁
more: (params.page) < data.total
}
};
},
cache: true
},
placeholder: '請選擇',//默認文字提示
language: "zh-CN",//語言
tags: true,//允許手動添加
allowClear: true,//允許清空
escapeMarkup: function (markup) { return markup; }, // 自定義格式化防止xss注入
minimumInputLength: 1,//輸入幾個字符后開始查詢,1:表示一個字符
templateResult: formatRepoProvince, //顯示的結果集格式,這里需要自己寫css樣式
templateSelection: formatRepoProvince //選擇某一項后顯示到文本框的內容
});
//$("#sel_4").trigger('change');//使用append拼接時需重新渲染
});
//編寫樣式
function formatRepoProvince(repo) {
console.log(repo);
if (repo.loading) return repo.text;
var imgs = repo.img;
imgs = imgs.substring(1, imgs.length);
var markup = '<span><img src="' + imgs + '" style="width: 5%;height:5%" class="img-flag"/> ' + repo.text + '</span>';
return markup;
}
</script>
效果:
設置默認值:
$('#sel_4').val(['2']).trigger('change');//其中2是id或者value的值,是list格式。change是固定值
option分頁實現
如果option 太多 直接渲染,頁面渲染會很慢,這時候就要分頁,分頁如何實現呢?
文檔:https://select2.org/data-sources/ajax
下面是個參考
js
//標簽
$('#materiasort2').select2({
width:'100%',
//提示語
placeholder: '請選擇標簽',
/*//在用戶停止輸入250毫秒后開始查詢
delay: 250,
//輸入指定2個字符后開始搜索
minimumInputLength: 2,*/
ajax: {
//請求后端分頁數據的url
url: '{:url("index/material/keywordList")}',
type: "POST",
data: function (params) {
var query = {
search: params.term,
page: params.page || 1
}
// Query parameters will be ?search=[term]&page=[page]
return query;
}
}
})
后端(php,tp5.1)
//標簽分頁
public function keywordList(){
//頁碼
$page = input('page');
//每頁條數
$pageSize = 15;
$keywordList = KeywordsModel::where('active',1)->limit(($page - 1) * $pageSize, $pageSize)->select();
//查詢是否有下一頁
$nextCount = KeywordsModel::where('active',1)->limit($page * $pageSize, $pageSize)->select()->count();
//返回格式
/*
*{
"results": [
{
"id": 1,
"text": "Option 1"
},
{
"id": 2,
"text": "Option 2"
}
],
"pagination": {
"more": true
}
}
*
*/
$results = array();
$pagination = array();
//遍歷數據
foreach ($keywordList as $keyword){
$temp = array();
$temp['id'] = $keyword->id;
$temp['text'] = $keyword->title;
$results[] = $temp;
}
//有下一頁
if($nextCount > 0){
$pagination['more'] = true;
}else{
$pagination['more'] = false;
}
$data = [
'results' => $results,
'pagination' => $pagination,
];
return json($data);
}
ajax方式加載數據,編輯數據回顯
//標簽
var materiasort2SelectNode = $('#materiasort2').select2({
width:'100%',
//提示語
placeholder: '請選擇標簽',
ajax: {
//請求后端分頁數據的url
url: '{:url("index/material/keywordList")}',
type: "POST",
data: function (params) {
var query = {
search: params.term,
page: params.page || 1
}
// Query parameters will be ?search=[term]&page=[page]
return query;
}
}
})
function edit(id) {
$('#modal-edit').modal('toggle');
$('#edit-id').prop("value", id);
//注意先清空選中,不然會每點擊一次增加一組option
$('#materiasort2').val(null).trigger('change');
$.ajax({
url: '{:url("index/material/edit")}',
type: 'post',
data: {id: id, action: 1},
success: function (res) {
//后端返回的是keywordss 數組
for(var i = 0; i < res.keywordss.length; i++){
//這種方式無效
//keywordssList[keywordssList.length] = res.keywordss[i].id;
/* var option = document.createElement('option');
option.value = res.keywordss[i].id;
option.innerText = res.keywordss[i].title;*/
//這種可以 第一個參數是option中間的文字,第二個是value 第三個位是否默認選中 第四個是否選中
var option = new Option(res.keywordss[i].title, res.keywordss[i].id, true, true);
//materiasort2SelectNode 為select2 初始化返回的dom
materiasort2SelectNode.append(option);
}
materiasort2SelectNode.trigger('change');
}
});
}
設置下拉框和隱藏下拉框
select2中有一個屬性,可以設置下拉位置,所以可以根據這個屬性設置下拉框顯示位置,隱藏的話可以設置disabled,但是這樣輸入框額去掉選擇就不能用了。所以可以用這種方式將下拉框顯示到一個隱藏塊中
官方文檔:https://select2.org/dropdown
例:
<!--select2 隱藏塊-->
<div id="myModal" style="display: none">
</div>
$('#id_select2_edit').select2({
placeholder: '選擇標簽',
//將下拉框放到一個不顯示塊,屏蔽下拉框
dropdownParent: $('#myModal'),
})
清除選中觸發的事件
select2 所有事件:https://select2.org/programmatic-control/events
//select 2 事件注冊 移除選中
$('#id_select2_edit').on("select2:unselect", function (e) {
//事件對象
console.log(e,11111111111111111);
//select 參數
console.log(e.params.data,22222222222);
})
參考:
select2 所有事件:
https://select2.org/programmatic-control/events
https://blog.csdn.net/jiangeeq/article/details/52457351
https://blog.csdn.net/jiangeeq/article/details/52457351