從0到87實作Select2
下拉式選單的87種變化
================= 取得書籍類別+關鍵字搜索(單選與多選) Start =================
【NormalController】
public ActionResult Index()
{
var allBooks = GetBooksList();
var distinctCategories = allBooks.Select(x => x.Category).Distinct();
ViewBag.AllCategories = new SelectList(distinctCategories);
return View();
}
[HttpPost]
public ActionResult Index(string NormalSelect, string[] MultiSelect)
{
return View();
}
NormalController -【Index】
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<string>取得書籍類別+關鍵字搜索</string>
@Html.DropDownList("NormalSelect", (IEnumerable<SelectListItem>)ViewBag.AllCategories, null, new { @class = "form-control", @id = "NormalSelect" })
<string style="color:red">單選,會預設第一個選項為已選擇 </string>
<br /><br />
<string>取得書籍類別+關鍵字搜索(多選)</string>
@Html.DropDownList("MultiSelect", (IEnumerable<SelectListItem>)ViewBag.AllCategories, null, new { @class = "form-control", @id = "MultiSelect", @multiple = "multiple", @style = "width:580px" })
<string style="color:red">多選,不會預設選項 </string>
<br /><br />
<input type="submit" value="提交此頁面"/>
}
@section Scripts
{
<script type="text/javascript">
$(document).ready(function () {
//========取得書籍類別+關鍵字搜索 Start========
$("#NormalSelect").select2(); //單選,會預設第一個選項為已選擇
$("#MultiSelect").select2({ //多選,不會預設選項
placeholder: "@@Html.DDL(.., new {@@multiple = \"multiple\" })"
});
//========取得書籍類別+關鍵字搜索 End========
})
</script>
}
13行 若要讓下拉選單為多選,則需要添加@multiple="multiple"的屬性,此為其中一種添加的方式
29行 placeholder 即為浮水印的效果
實際多選時,效果如下
提交此頁面,將值傳送到Controller
註:注意Controller接收的名稱與型別
================= 取得書籍類別+關鍵字搜索(單選與多選) End =================
================= 取得書籍類別+關鍵字搜索(多選-最多三項;最多輸入5個字元;最少輸入2個字元) Start =================
此效果只需關注Index頁面的改動
NormalController -【Index】
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<string>取得書籍類別+關鍵字搜索(多選-最多三項)</string>
@Html.DropDownList("MultiSelectLimit3", (IEnumerable<SelectListItem>)ViewBag.AllCategories, null, new { @class = "form-control", @id = "MultiSelectLimit3", @multiple = "multiple" })
<br /><br />
<string>取得書籍類別+關鍵字搜索(最多輸入5個字元)</string>
@Html.DropDownList("MultiSelectMaximumInputLength5", (IEnumerable<SelectListItem>)ViewBag.AllCategories, null, new { @class = "form-control", @id = "MultiSelectMaximumInputLength5", @multiple = "multiple", @maximumInputLength = 5 })
<br /><br />
<string>取得書籍類別+關鍵字搜索(最少輸入2個字元)</string>
@Html.DropDownList("MultiSelectMinimumInputLength2", (IEnumerable<SelectListItem>)ViewBag.AllCategories, null, new { @class = "form-control", @id = "MultiSelectMinimumInputLength2", @multiple = "multiple", @minimumInputLength = 2 })
<br /><br />
<input type="submit" value="提交此頁面" />
}
@section Scripts
{
<script type="text/javascript">
$(document).ready(function () {
//========取得書籍類別+關鍵字搜索(多選-最多三項) Start========
$("#MultiSelectLimit3").select2({
maximumSelectionLength: 3,
placeholder: "maximumSelectionLength : integer"
});
//========取得書籍類別+關鍵字搜索(多選-最多三項) End========
//========取得書籍類別+關鍵字搜索(最多輸入5個字元) Start========
$("#MultiSelectMaximumInputLength5").select2({
maximumInputLength: 5,
placeholder: "maximumInputLength : integer"
});
//========取得書籍類別+關鍵字搜索(最多輸入5個字元) End========
//========取得書籍類別+關鍵字搜索(最少輸入2個字元) Start========
$("#MultiSelectMinimumInputLength2").select2({
minimumInputLength: 2,
placeholder: "minimumInputLength : integer"
});
//========取得書籍類別+關鍵字搜索(最少輸入2個字元) End========
})
</script>
}
寫在@Html後 (12,16行) 或是在select2({})宣告(30,37,44行) 都是一樣的效果,擇一就行了。
實際上的效果如下圖
================= 新增空白選項作為預設;若不存在則新增一個選項Start =================
【NormalController】
public ActionResult Index()
{
var allBooks = GetBooksList();
var distinctCategories = allBooks.Select(x => x.Category).Distinct();
ViewBag.AllCategories = new SelectList(distinctCategories);
List<SelectListItem> selectListItems = new List<SelectListItem>();
var specificFieldsOfBook = allBooks.Select(x => new
{
id = x.Id,
text = x.Author + "-" + x.Name,
Category = x.Category.ToString()
});
ViewBag.AllBooksWithoutSelected = new SelectList(specificFieldsOfBook, "id", "text");
return View();
}
[HttpPost]
public ActionResult Index(string AddDefaultOption,string CreateIfNotExist)
{
return View();
}
新增一個ViewBag
NormalController -【Index】
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<string>新增空白選項作為預設</string>
@Html.DropDownList("AddDefaultOption", (IEnumerable<SelectListItem>)ViewBag.AllBooksWithoutSelected, null, new { @class = "form-control", @id = "AddDefaultOption" })
<br /><br />
<string>若不存在則新增一個選項</string>
@Html.DropDownList("CreateIfNotExist", (IEnumerable<SelectListItem>)ViewBag.AllBooksWithoutSelected, null, new { @class = "form-control", @id = "CreateIfNotExist" })
<br /><br />
<input type="submit" value="提交此頁面" />
}
@section Scripts
{
<script type="text/javascript">
$(document).ready(function () {
//======== 新增空白選項作為預設 Start========
var emptyOption = {
id: -94,
text: "新增的預設選項"
};
/*第三個建構子為-是否在html上加上selected 但僅止於selected
必須和第四個建構子同時為true,才能讓新增的選項成為default selected*/
var newOption = new Option(emptyOption.text, emptyOption.id, true, true);
/* Select2 will listen for the change event on the <select> element that
* it is attached to. When you make any external changes that need to
* be reflected in Select2 (such as changing the value),
* you should trigger this event.*/
$("#AddDefaultOption").append(newOption).trigger('change'); // Notify any JS components that the value changed
//======== 新增空白選項作為預設 End========
//======== Create if not exists Start========
//尋找「新增的預設選項」是否存在,不存在則新增
var AnotherOption = {
id: -87,
text: "若不存在則新增的預設選項"
};
if ($("#CreateIfNotExist").find("option[value='" + AnotherOption.id + "']").length) {
$('#CreateIfNotExist').val(AnotherOption.id).trigger('change');
} else {
var newOption = new Option(AnotherOption.text, AnotherOption.id, true, true);
$('#CreateIfNotExist').append(newOption).trigger('change');
}
//======== Create if not exists End========
})
</script>
}
30行 new Option(建構子1,2,3,4) 1:Text ; 2:Value ; 3:是否在html上加上selected ; 4: 搭配3 可輸入false 按F12自行比較差別
36行 使用append將24-30行新增的空白選項,加入("#AddDefaultOption")中 任何對內容的改變都需要透過.trigger('change')來告訴JS重新render畫面
43-52行是差不多的概念,只差在多一個判別,先去找看看("#CreateIfNotExist")裡面有沒有AnotherOption這個選項,沒有則新增
實際結果如下圖
若直接按下提交 Controller會接到
================= 新增空白選項作為預設;若不存在則新增一個選項End =================
================= AllowClear Start =================
此效果僅需關注Index頁面
NormalController-【Index】
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<string>選項AllowedClear</string>
@Html.DropDownList("NormalSelectAllowedClear", (IEnumerable<SelectListItem>)ViewBag.AllCategories, null, new { @class = "form-control", @id = "NormalSelectAllowedClear" })
<string style="color:red"> 有x符號可以清空該選項 就不用寫一個空白選項</string>
<br /><br />
<string>選項NotAllowedClear</string>
@Html.DropDownList("MultiSelectNotAllowedClear", (IEnumerable<SelectListItem>)ViewBag.AllCategories, null, new { @class = "form-control", @id = "MultiSelectNotAllowedClear" })
<br /><br />
<input type="submit" value="提交此頁面" />
}
@section Scripts
{
<script type="text/javascript">
$(document).ready(function () {
//========選項AllowClear Start========
$("#NormalSelectAllowedClear").select2({
placeholder: "allowClear : true",
allowClear: true
})
//========選項AllowClear End========
//========選項NotAllowClear Start========
$("#MultiSelectNotAllowedClear").select2({
placeholder: "allowClear : false",
allowClear: false //預設為false
})
//========選項NotAllowClear End========
})
</script>
}
實際效果如下圖
補充一下好惹 如果post到Controller,接到的值會是
================= AllowClear End =================
================= 選擇後自動關閉;關閉時選擇反白選項 Start =================
此效果僅需關注Index頁面
NormalController-【Index】
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<string>選擇後自動關閉選單(預設)</string>
@Html.DropDownList("closeOnSelectTrue", (IEnumerable<SelectListItem>)ViewBag.AllCategories, null, new { @class = "form-control", @id = "closeOnSelectTrue", @multiple = "multiple" })
<br /><br />
<string>選擇後不關閉選單(點兩下才關閉)</string>
@Html.DropDownList("closeOnSelectFalse", (IEnumerable<SelectListItem>)ViewBag.AllCategories, null, new { @class = "form-control", @id = "closeOnSelectFalse" })
<string style="color:red">選擇後不關閉選單(點兩下才關閉) 不能搭配Multiple使用!</string>
<br /><br />
<string>關閉後自動選擇已反白的選項</string>
@Html.DropDownList("selectOnCloseTrue", (IEnumerable<SelectListItem>)ViewBag.AllCategories, null, new { @class = "form-control", @id = "selectOnCloseTrue", @multiple = "multiple" })
<br /><br />
<input type="submit" value="提交此頁面" />
}
@section Scripts
{
<script type="text/javascript">
$(document).ready(function () {
//========選擇後自動關閉選單 Start========
$("#closeOnSelectTrue").select2({
placeholder: "選擇後自動關閉選單(預設)",
closeOnSelect: true
});
//"選擇後不關閉選單(點兩下才關閉) 不能搭配Multiple使用!"
$("#closeOnSelectFalse").select2({ closeOnSelect: false });
//========選擇後自動關閉選單 End========
//========關閉後自動選擇已反白的選項 Start========
$("#selectOnCloseTrue").select2({
placeholder: "關閉後自動選擇已反白的選項",
selectOnClose: true,
});
//========關閉後自動選擇已反白的選項 End========
})
</script>
}
32行 預設為true ,選了某項就直接關閉選單
36行 若改為false,選擇選項時需同一個選項兩次才會關閉(無法搭配multiple使用)
42行 點開下拉選單,若滑鼠移到某個選項,接著點選選單以外的地方關閉選單,此時就會自動選擇被反白的選項
點擊其他地方關閉選單時,就會自動選擇台灣文學
================= 選擇後自動關閉;關閉時選擇反白選項 End =================
我沒有做出來,或沒有特別做的部分如下
/*補充
1.清空選項
$('#mySelect2').val(null).trigger('change');
2.取得被選取的選項
2-1 Using a jQuery selector $('#mySelect2').find(':selected');
2-2 Using the data method $('#mySelect2').select2('data');
3.destroy The destroy method will remove the Select2 widget from the target element. It will revert back to a standard select control:
$('#mySelect2').select2('destroy');
//效果參考https://select2.org/programmatic-control/methods
4.Listening for events
$('#mySelect2').on('select2:select', function (e) { Do something});
*/