用了這麼久的Select2插件,也該寫篇文章總結總結。當初感受Select2不是特別好用,但又找不到比它更好的下拉框插件。javascript
在個人印象裏Select2有2個版本,最新版本有一些新的特性,而且更新了一下方法參數,比最第一版本要好看一些,本文針對新版本。css
官網:http://select2.github.io/ html
演示:前端
因爲博客系統的緣由,因此只能演示簡單的功能。java
一.文件須要引入select2.full.js、select2.min.css(4.0.1版本)和jQuery.1.8.3及以上mysql
最新版本的select2若是引用的jquery版本較低的話,某些功能沒法正常使用。好比:清除功能allowClear: truejquery
最新版本請使用<select></select>標籤(對於本地化的數據你可使用input,但ajax遠程數據必須使用select)git
二.placeholdergithub
placeholder佔位提示文字,若是須要清楚功能,則必須設置placeholder。ajax
三.加載本地數據
select2默認的數據屬性是id、text,新版本能夠自定義,但仍是用默認的比較好。因此提供的json中最好轉換爲id、text形式,固然能夠添加其餘屬性。
var data = [{ id: 0, text: 'enhancement' }, { id: 1, text: 'bug' }, { id: 2, text: 'duplicate' }, { id: 3, text: 'invalid' }, { id: 4, text: 'wontfix' }];
$("#c01-select").select2({
data: data,
placeholder:'請選擇',
allowClear:true
})
四.加載遠程數據
$("#c01-select").select2({
ajax: {
url: "data.json",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term,
};
},
processResults: function (data) {
return {
results: data
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 1,
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
說明:
1.q: params.term 查詢參數(params.term表示輸入框中內容,q發生到服務器的參數名;因此這裏你能夠添加自定義參數,如:stype:'person')
2.processResults中results: data返回數據(返回最終數據給results,若是個人數據在data.res下,則返回data.res。這個與服務器返回json有關)
3.minimumInputLength 最小須要輸入多少個字符才進行查詢,與之相關的maximumSelectionLength表示最大輸入限制。
4.escapeMarkup字符轉義處理
5.templateResult返回結果回調function formatRepo(repo){return repo.text},這樣就能夠將返回結果的的text顯示到下拉框裏,固然你能夠return repo.text+"1";等
6.templateSelection選中項回調function formatRepoSelection(repo){return repo.text}
7.關於返回的 json的格式:select2默認json格式爲[{id:1,text:'text'},{id:2,text:'text'}],新版嚴格要求這樣的格式,固然你能夠添加列,如:[{id:1,text:'text',name:'liu'}]
五.獲取選中項
var res=$("#c01-select").select2("data")[0] ; //單選
var reslist=$("#c01-select").select2("data"); //多選
if(res==undefined)
{
alert("你沒有選中任何項");
}
if(reslist.length)
{
alert("你選中任何項");
}
六.清空選擇項和設置不可用
//清空選擇 $("#c01-select").val(null).trigger("change"); $("#c01-select").val("你的placeholder").trigger("change");//或者
//若是你使用的是input標籤(默認就是本地數據),你能夠用$("#c01-select").val('');來清空選項
//disabled
$("#c01-select").prop("disabled", false);//可用
$("#c01-select").prop("disabled", true);//不可用
七.啓用多選
$("#c01-select").select2({
data:data,
multiple: true
});
多選演示:
因爲博客系統緣由只能演示選擇
八.下面簡單說明新版與老版對比
1.結果回調和選中回調名稱:formatResult、formatSelection(老版);templateResult、templateSelection(新版)
2.初始化:
//老版,注意若是初始化時文本框中自己沒有值(爲空),則不會觸發該方法
initSelection: function (element, callback) { var id = $(element).val(); var data = { id: id, text: id};//這裏是初始化的數據,你能夠經過id來從服務器上獲取(ajax),再裝載進去 callback(data); }
//新版,直接給select添加option
$("#id").append(new Option("Jquery", 10001, false, true)); //或者 $("#id").append("<option value='10001'>Jquery</option>");
3.獲取或設置值:select2("val")(老版);$("select").val()(新版)
推薦使用
var res = $("#id").select2("data");
//返回數組,單選就取res[0];好處是不進能夠獲取id、text還能夠獲取其餘屬性,如res[0].names
4.停用或啓用:$("select").enable(false);(老版);$("select").prop("disabled", true);(新版)
5.主題樣式:新版的樣式已經更新,但若是想使用老版樣式則能夠設置 theme: "classic"
這個插件是基於Select的擴展插件,可以提供更加豐富的功能和用戶體驗,它的github官網地址爲:https://select2.github.io/,具體的使用案例,能夠參考地址:https://select2.github.io/examples.html。
咱們在整個框架裏面,用到了不少Select2控件來處理內容的顯示,包括單選的下拉列表(包括級聯選擇框)、複選的下拉列表、樹形下拉列表等方式,界面效果以下所示。
1)編輯界面下的省份、城市、所在行政區的級聯界面效果,選擇省份,會加載對應省份下的城市,選擇城市,會繼續加載城市下的行政區,從而實現多級關聯的下拉列表效果。
2)編輯界面下的多項選擇下拉列表
但咱們選擇其中的內容的時候,系統自動顯示出沒有選擇的列表數據,很是直觀友好,以下所示。
3)樹形列表的下拉列表
有時候,咱們的一些數據可能有層次關係的,如所屬機構、上層列表等等。
使用select2控件,通常是在常規的select控件上,設置一下便可(設置它的class爲select2)。
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-4">重要級別</label>
<div class="col-md-8">
<select id="Importance" name="Importance" class="form-control select2" placeholder="重要級別..."></select>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-4">承認程度</label>
<div class="col-md-8">
<select id="Recognition" name="Recognition" class="form-control select2" placeholder="承認程度..."></select>
</div>
</div>
</div>
若是是固定列表,那麼也就是設置它的Option內容便可,以下所示。
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-4">吸菸</label>
<div class="col-md-8">
<select id="Smoking" name="Smoking" type="text" class="form-control select2" placeholder="吸菸...">
<option>吸菸</option>
<option>不吸菸</option>
</select>
</div>
</div>
</div>
簡單的select2控件初始化代碼以下所示。
$(document).ready(function() {
$(".js-example-basic-single").select2();
});
通常狀況下,若是容許複選多個項目,那麼設置 multiple="multiple"便可,以下代碼所示。
<select id="ResponseDemand" name="ResponseDemand" multiple="multiple" class="form-control select2"></select>
通常狀況下,咱們的select控件的數據,是從數據庫裏面動態加載的,所以通常是經過Ajax方式獲取數據並進行綁定便可。
基於代碼可重用性的考慮,咱們編寫一個公用的JS函數,用來減小綁定操做的代碼,提升代碼重用性。
//綁定字典內容到指定的Select控件
function BindSelect(ctrlName, url) {
var control = $('#' + ctrlName);
//設置Select2的處理
control.select2({
allowClear: true,
formatResult: formatResult,
formatSelection: formatSelection,
escapeMarkup: function (m) {
return m;
}
});
//綁定Ajax的內容
$.getJSON(url, function (data) {
control.empty();//清空下拉框
$.each(data, function (i, item) {
control.append("<option value='" + item.Value + "'> " + item.Text + "</option>");
});
});
}
這樣,綁定公用字典模塊的數據,也就能夠經過下面進一步封裝處理便可。
//綁定字典內容到指定的控件
function BindDictItem(ctrlName, dictTypeName) {
var url = '/DictData/GetDictJson?dictTypeName=' + encodeURI(dictTypeName);
BindSelect(ctrlName, url);
}
這樣咱們初始化Select2 控件,並動態綁定對應的字典值或者其餘數據,則能夠經過下面初始化代碼便可實現。其中BindDictItem就是直接綁定字典內容的操做,BindSelect則是根據URL進行數據的獲取並綁定,而$("#Province").on("change", function (e) {});這樣的函數處理,就是處理選擇內容變化的聯動操做了。
//初始化字典信息(下拉列表)
function InitDictItem() {
//部分賦值參考
BindDictItem("Area","市場分區");
BindDictItem("Industry", "客戶行業");
BindDictItem("Grade","客戶級別");
BindDictItem("CustomerType", "客戶類型");
BindDictItem("Source", "客戶來源");
BindDictItem("CreditStatus", "信用等級");
BindDictItem("Stage","客戶階段");
BindDictItem("Status", "客戶狀態");
BindDictItem("Importance", "重要級別");
// 綁定省份、城市、行政區(聯動處理)
BindSelect("Province", "/Province/GetAllProvinceNameDictJson");
$("#Province").on("change", function (e) {
var provinceName = $("#Province").val();
BindSelect("City", "/City/GetCitysByProvinceNameDictJson?provinceName="+ provinceName);
});
$("#City").on("change", function (e) {
var cityName = $("#City").val();
BindSelect("District", "/District/GetDistrictByCityNameDictJson?cityName="+ cityName);
});
}
而其中MVC控制器返回的數據,咱們是返回一個JSON數據列表給前端頁面的,他們的數據格式以下所示。
[ { "Text": "", "Value": "" }, { "Text": "學術會議", "Value": "學術會議" }, { "Text": "朋友介紹", "Value": "朋友介紹" }, { "Text": "廣告媒體", "Value": "廣告媒體" } ]
這樣前端頁面綁定Select2控件的時候,就使用了JSON對象的屬性便可。
//綁定Ajax的內容
$.getJSON(url, function (data) {
control.empty();//清空下拉框
$.each(data, function (i, item) {
control.append("<option value='" + item.Value + "'> " + item.Text + "</option>");
});
});
控制器的實現代碼以下:
/// <summary>
/// 根據字典類型獲取對應的字典數據,方便UI控件的綁定
/// </summary>
/// <param name="dictTypeName">字典類型名稱</param>
/// <returns></returns>
public ActionResult GetDictJson(string dictTypeName)
{
List<CListItem> treeList = new List<CListItem>();
CListItem pNode = new CListItem("", "");
treeList.Insert(0, pNode);
Dictionary<string, string> dict = BLLFactory<DictData>.Instance.GetDictByDictType(dictTypeName);
foreach (string key in dict.Keys)
{
treeList.Add(new CListItem(key, dict[key]));
}
return ToJsonContent(treeList);
}
對於屬性列表,如所屬公司、所屬部門機構等有層次性的數據,它的綁定操做也是相似的,以下代碼所示。
//綁定添加界面的公司、部門、直屬經理
BindSelect("Company_ID", "/User/GetMyCompanyDictJson?userId="+@Session["UserId"]);
$("#Company_ID").on("change", function (e) {
var companyid = $("#Company_ID").val();
BindSelect("Dept_ID", "/User/GetDeptDictJson?parentId="+ companyid);
});
$("#Dept_ID").on("change", function (e) {
var deptid = $("#Dept_ID").val();
BindSelect("PID", "/User/GetUserDictJson?deptId="+ deptid);
});
只是它們返回的數據,咱們把它做爲有縮進的顯示內容而已。
[ { "Text": "愛奇迪集團", "Value": "1" }, { "Text": " 廣州分公司", "Value": "3" }, { "Text": " 上海分公司", "Value": "4" }, { "Text": " 北京分公司", "Value": "5" } ]
或者以下所示
[ { "Text": "廣州分公司", "Value": "3" }, { "Text": "總經辦", "Value": "6" }, { "Text": "財務部", "Value": "7" }, { "Text": "工程部", "Value": "8" }, { "Text": "產品研發部", "Value": "9" }, { "Text": " 開發一組", "Value": "14" }, { "Text": " 開發二組", "Value": "15" }, { "Text": " 測試組", "Value": "16" }, { "Text": "市場部", "Value": "10" }, { "Text": " 市場一部", "Value": "23" }, { "Text": " 市場二部", "Value": "24" }, { "Text": "綜合部", "Value": "11" }, { "Text": "生產部", "Value": "12" }, { "Text": "人力資源部", "Value": "13" } ]
綜上兩個部分,咱們能夠看到它們的Text的內容,是根據層次關係進行空格增長,從而實現了層次關係的顯示。
不過從這個界面效果上講,這樣的處理確實沒有EasyUI裏面,對下拉列表樹的展現好看,也許能夠利用更好的Bootstrap插件進行這個樹形內容的展現。
上面介紹的方法,都是介紹select2控件的初始化,綁定相關的數據,那麼若是初始化界面後,咱們綁定編輯界面的值的時候,就須要賦值給控件,讓它顯示真正須要顯示的項目了。
如清空控件的方法以下所示。
//清空Select2控件的值
$("#PID").select2("val", "");
$("#Company_ID").select2("val", "");
$("#Dept_ID").select2("val", "");
若是對於多個控件,須要清除,則可使用集合進行處理
var select2Ctrl = ["Area","Industry","Grade","CustomerType","Source","CreditStatus","Stage","Status","Importance"];
$.each(select2Ctrl, function (i, item) {
var ctrl = $("#" + item);
ctrl.select2("val", "");
});
給Select2 控件賦值,讓它顯示對應值內容的項目,那麼操做也就和上面的相似了。
$("#CustomerType").select2("val", info.CustomerType);
$("#Grade").select2("val", info.Grade);
$("#CreditStatus").select2("val", info.CreditStatus);
$("#Importance").select2("val", info.Importance);
$("#IsPublic").select2("val", info.IsPublic);
若是須要級聯顯示的,那麼作法增長一個onchange的函數處理就能夠了,以下級聯代碼的賦值處理以下。
$("#Province").select2("val", info.Province);
$("#Province").trigger('change');//聯動
$("#City").select2("val", info.City);
$("#City").trigger('change');//聯動
$("#District").select2("val", info.District);
$("#Company_ID1").select2("val", info.Company_ID);
$("#Company_ID1").trigger('change');
$("#Dept_ID1").select2("val", info.Dept_ID);
$("#Dept_ID1").trigger('change');
$("#PID1").select2("val", info.PID);
多個列表項目數據的綁定。
咱們從案例裏面能夠看到,Select2支持多項值的選擇,它們保存後會以逗號分開,若是咱們須要在編輯的時候顯示存儲的多個記錄,那麼須要把字符串轉換爲數組列表才能進行正確綁定,以下所示。
$("#Permission").select2("val", info.Permission.split(','));
最後來兩個總體性的界面效果,供參考。