Select2
原生 <select>
标签没有 美化和 DOM 事件,没有模糊搜索,从后端获取数据时要自行插入选项,小码农真是伤不起。于是在 AdminLTE 中找到一款叫 Select2 的 jQuery 插件。它支持多语言、远端数据搜索、个性化主题,这一切还基于简洁易懂的 jQuery。
快速使用
1.在 <head>
标签内加入 CDN 地址,当然别忘了这玩意需要 jQuery :
<link href="https://cdn.staticfile.org/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/select2/4.0.3/js/select2.min.js"></script>
2.使用 <select>
标签来初始化该插件:
<select name="brand">
<option value ="volvo">Volvo</option>
<option value ="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
$(document).ready(function() {
$('select').select2({
placeholder:'Select a state',
});
});
Result
进阶
往往在项目中会遇到更复杂的需求。从后端获取数据到本地渲染,单选或多选的功能。
本地数据
在请求远端之前,不妨先试试读取本地的数据,供用户选择。Select2
建议使用这样约定好的格式:
var data = [
{ id: 0, text: 'enhancement' },
{ id: 1, text: 'bug' },
{ id: 2, text: 'duplicate' },
{ id: 3, text: 'invalid' },
{ id: 4, text: 'wontfix' }
];
Prop | Type | Example | Description |
---|---|---|---|
id | Number/String | 0 | 区分选项的唯一值 |
text | String | "bug" | 选中时显示的文字 |
id
作为 表单对象的值(value),text
作为选项的文本。这样子规定的好处是既能替代原生下拉列表,又不失去其 表单键值 和 选项显示 功能。
这样尝试在初始化的时候使用 本地的 data
对象作为 Select2
的选项。
觉得搜索没必要?关闭掉就好了
$('select').select2({
placeholder:'Select a state',
data: data,
minimumResultsForSearch: Infinity //Hiding the search box
});
现在来看看可以使用自定义的数据来作子选项了
远端数据
显然可以使用远端数据来实现一个复杂可搜索的下拉列表。官方的栗子使用了 Github 搜索仓库的 API 接口作示范,尝试一步步地来读懂它。
var $ajax = $("select");
$ajax.select2({
ajax: {
url: "https://api.github.com/search/repositories",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) {
return markup;
},
minimumInputLength: 1,
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
function formatRepo(repo) {
if (repo.loading) return repo.text;
var markup = "";
//ellipsis. looking for follows...
return markup;
}
function formatRepoSelection(repo) {
return repo.full_name || repo.text;
}
ajax
url
指定了接口的地址。
栗子中的地址直接访问不能得到想要的数据,必须带一些参数,通过接口文档 可知道,加上?q=bootstrap
即可查询名为bootstrap
的仓库信息。data
需配合上面url
的规定来组合成正确的查询参数,栗子中通过一个匿名函数处理后返回实际的q
和page
作为接口中的参数。params.term
是用户输入的内容,稍作处理可作为接口的参数,params.page
也是一个自定义的参数值。processResults
对象可对接口返回的结果作处理,results
参数这里头的数据(一般为数组)稍后会用来绘制下拉的列表项。这里取 ajax 返回数据中 items 数组 作为处理结果。items 中单个元素中有一些id
name
full_name
avatar_url
description
数据。
escapeMarkup 返回字符串作为 DOM
树的绘制结果,一般默认即可。
minimumInputLength 用户至少要输入几个字符才触发搜索,也会在界面上提示用户。
templateResult 绘制每条子选项时执行的函数。
传入一个参数,即 processResults
函数处理后 results
的单个元素,其中包括了一些 id
name
full_name
等数据 。
通过字符串来创建子选项的模板,使用传入repo
参数来将要显示的数据填入模版中。当然在这里还可以判断某些参数是否存在,以绘制不同的子选项。最后返回字符串 markup
。
templateSelection 子选项被选择后执行的函数。
传入的参数同 templateResult
一样。
返回 full_name
或 text
来用于显示选中项的描述,让用户知道选中了哪一个选项。如果在 processResults
中对要显示的文本处理过,就不必再次去修改返回的 text
。
数据流动
整个流程中,其实是在处理一个相关数组,一个个元素渲染成列表。要注意的是,单条数据中的 id
作为 Select2
区分不同选项的重要依据,处理过后的数据中要确保 id
字段的存在。
Demo
分页
Select2
对分页查询非常友好,在接口设计中 page
等分页参数很常见,在一次查询中后台仅返回限定的条数,余下的数据需要再次请求,减少后端的负担。
processResults 中 pagination
的 more
作为 布尔变量决定 该次请求后,下一次是否继续请求。
pagination: {
more: (params.page * 30) < data.total_count
}
后端返回的 data.total_count
为搜索结果的条目数。第一次请求时 params.page
为 1 或不存在。若返回的数据是还有第二页且用户滚动列表到底部时,params.page
值 +1
后重新发出一条网络请求。
data
中 params.page
是 Select2
中内置的一个属性,保存着当前页数。若 pagination.more
为 真 时,该项 +1
并重新请求后端,返回的数据将添加到列表尾部。
参考资料
感谢两位作者 Kevin Brown & Igor Vaynberg