bootstrap下拉框分页_【Bootstrap】bootstrap-select2下拉菜
单插件
这次开发了个⼩TRS系统,虽然是很⼩,但是作为初⼼者,第⼀次⽤到了很多看起来洋⽓使⽤起来有相对简单的各种前端(主要是和bootstrap配合使⽤)组件。包括bootstrap-select2,bootstrap-datetimepicker,bootstrap-fileinput等。本⽂就旨在记录⼀些这些组件相关的内容
【bootstrap-select2】
这个组件主要⽤于优化等页⾯组件。⽐如我们想要在下拉菜单的顶部加上⼀个搜索框⽀持我们对选项进⾏搜索,抑或是在多选下拉菜单中我们要有那种类似于tag形式的表现,⽤这个组件就很好了。⾸先是这个组件需要在页⾯中进⾏引⼊的⽂件:
zh-CN.js是语⾔翻译⽂件,需要注意引⼊必须在select2.min.js后⾯,否则会报错。这⼀点也适⽤于绝⼤多数⽀持国际化显⽰的组件。
当然因为是bootstrap的组件,⾃然是不能少bootstrap的js和css以及⽀持bootstrap的jquery了,这个就不写出来了。
■  带静态搜索框的下拉菜单
所谓静态搜索框,就是指这个下拉菜单⾥所有的option都是在页⾯渲染时就已经固化好了的,⽤这个搜索框进⾏搜索时不会动态发请求到后台去取数据。这个搜索框的HTML可以这么写:
1
2
3
这就是⼀个普通的select,只不过需要有form-control这个class和⼀个⽤于后续表⽰⽤的id。
然后在js中这么写:
$('#static_dropdown').select2({
language: 'zh-CN',
width: '100%',
placeholder: '请选择',
minimumInputLength: 10});
利⽤前端组件⼀个⾮常重要的内容就是把握初始化时各个初始化参数的含义。通过对不同参数发出调整来搞出⼀个符合⾃⼰需求的组件。
这⾥⽤到的四个参数,language显⽽易见是国际化显⽰⽤的。width指出了这个select的宽度,placeholder就是
<,minimunInputLength指出了在搜索时⾄少要输⼊多少字符才会给出响应的搜索结果。如果待选项不是太多的话尽量不要设置过⼤的值,像⽰例的10,我觉得是很⼤的⼀个值了。。
下⾯也会零散性地给出⼀些参数说明:
selectOnClose  当设置成true时,当收起菜单时的⾼亮项会⾃动被选择,如果是false则不会⾃动选择。
dropdownParent  可以指定下拉菜单在html代码中的位置。默认情况下,下拉菜单都是被append到body中,并且被设置成position:absolute,且位置在select的下⽅。⽽设置这个参数⽐如dropdownParent: $('#myModal'),就可以将下拉菜单放⼊⼀个指定的容器中。
tags  把tags设置成true了之后,在搜索时即便没有搜索到相关内容,也会把你输⼊的内容当成⼀个可选项。之所以被称为tags,就是因为tags这个东西不⼀定要都是既存的,可以有⾮既存⽽我们⾃⼰添
加的情况。
placeholder  如果值是⼀个字符串那么就是⼀个简单的placeholder,如果换成⼀个对象也可以,即为菜单添加⼀个默认的选项。⽐如placeholder: {id:-1,text:'--请选择--'}
tokenSeparators  可以设置成⼀个包含各种字符的列表如[',',' '],常和tags以及多选菜单配合使⽤。即⾃⼰输⼊时,输⼊逗号或空格(看你这个参数设置的情况)时认为是⼀个tag的终结,就把前⾯的内容作为⼀个新tag添加到多选框⾥⾯。
createTag  这个参数的值也是⼀个函数对象。这个函数接受⼀个参数param,其结构是这样的
我们主要关注term这⼀项的值,我们可以在createTag指定的函数中对term进⾏⼀些逻辑判断和处理,然后返回⼀些结果来让添加标签的过程更加智能化⼀些。⽐如:
$('#testselect').select2({
createTag: function(param){
var term =$.);
if (term.indexOf('@') == -1){
return null;
}
else{
var id = term.split('@')[0];
var text = term.split('@')[1];
return{id:id,text:text};
}
}
});
在⽤户输⼊⾃定义的tag的时候可以检查存不存在@,如果不就不允许其增加这个tag,如果存在则@前⾯的部分作为value,后⾯的部分作为的text,加⼊⼀个新的tag。
minimunResultsForSearch  通常这个参数设置成⼀个整数,当option的待选数量⼤于这数字时才显⽰搜索框。当把这个参数设置为Infinity时将默认不显⽰搜索框即禁⽤搜索框。这样select就变成了⼀个simple的select了。
maximumSelectionLength  若是多选框,设置最多可以选择⼏项
另外,可以在select和option中引⼊⼀层optgroup标签并设置其label属性。optgroup可以为所有选项划分出合适的组分并且显⽰以label 的标签。将option的disabled设置为disabled还可以禁⽌选择某⼀个选项。
●  带有图⽚的下拉菜单
上⾯的说明,得到的下拉菜单都是纯⽂字的。其实select2⽀持我们传递图⽚进去作为每个选项的⼀个修饰。这⾥就要⽤到templateResult 这个参数。
⾸先要明确,我们虽然在html上写的是select和option,但是最终经过select2的加⼯呈现出来的是ul和li,每个li⾥⾯是当时option中的内容。在了解这⼀点的基础上,我们的templateResult参数是⼀个函数对象。这个函数对象接受⼀个object(这个object⼋成是select2内部定义的抽象了菜单选项的object)为参数并且返回字符串或jquery对象供select2渲染成菜单选项。简单来说,就是select2会对所有选项进
⾏⼀个遍历,依次执⾏⼀下这个函数然后按照我们定义的⽅式渲染出我们想要的菜单选项的样式和内容。⽐如下⾯这样:
templateResult: function(row){
return $(''++'');
}
上⾯这个函数有点绕,简单来说就是可以把/static/img/.png作为标识图⽚放在option的旁边。如果在这个函数中断点看下row的具体情况的话,就可以看到其实这个row的结构是这样的:
Object { selected: false, disabled: false, text: "张三", id: "10001", title: "", _resultId: "select2-addTrainSpeaker-result-5o5i-10001", element: option }
也就是说我们的option的value在这⾥是id,option的字符串在这⾥是text,这样就可以根据value和字符串来定制了。顺便⼀提,上⾯的函数中return要加上$()是因为不这样返回的默认是字符串,也就是每⼀项的内容都会变成xxxx的样⼦⽽不是html内容。所以返回jquery对象⽐较靠谱。
在编写templateResult函数的时候,还要注意对loading状态的处理。当打开下拉列表时,最先进⼊这
个函数的应该是loading状态的对象,此时row没有id属性,当时有loading:true属性,如果此时不返回当前的(正在加载中之类的提⽰⽂字)的话,渲染有可能就停⽌在这步。所以⼀般⽽⾔可以在templateResult函数⾥写上if(row.loading){;}之类的逻辑。
■  tag形式的多选框
所谓tag形式的多选框就是指这种:
这个看起来⽐较复杂,其实也通过select2实现也⽐较⽅便。html可以这么写:
+
a
b
c
然后在js中这样写:jquery滚动条滚动到底部
var multiple = $('#multiple_choice').select2({
placeholder: '请选择',
allowClear: true});
$('#multiple_all').click(function(event){
event.preventDefault();
var res =[];
$(this).next('select').find('option').each(function(i,ele){
res.push($(ele).val())
});
$(multiple).val(res).trigger('change');
});
第⼀部分很好理解,和上⾯的下拉菜单⼀样,也是初始化。只是这个初始化返回了⼀个jquery对象,
我们先⽤multiple这个变量保存下来。然后当select前⾯的那个按钮被点击时,就是执⾏了第⼆部分代码,是将select中所有选项的值都加⼊到⼀个数组中,然后把这个数组传递给刚才那个multiple对象的val⽅法,再trigger⼀下change事件。这样就可以⾃动地选择所有选项到多选框⾥⾯了。(这部分是我⾃⼰加上去,不是select2要求的)。
可以看出来$(multiple).val(xxx).trigger('change')就是拿来引发多选框被选中值变化的⽅法。如果xxx处填写null那么就是清空多选框了。
关于如何取值,类似的我们可以$('#multiple_choice').val()来取值,得到的应该是⼀个数组。这⾥多提⼀句,如何通过ajax传递数组给后台。直接写⼊ajax⽅法的data字段需要特殊处理过的数组。⽐如我们有数组对象array想要作为参数parti的值通过ajax传递出去的话,那么可以先JSON.stringify(array),得到的json化的字符串再拿来传递即可。在后台我们只要⽤相关后台的⽅法来解析json格式字符串即可。
■  编程控制
上⾯提到了如何⼀键清空或全选多选框的选项、这个其实是⼀个select2组件的编程控制。更⼀般地来说我们可以这样给下拉菜单多增加⼀个选项:
var data ={
id: 1,
text: 'test'};
var newOption = new ,data.id,false,false);
$('#testselect').append(newOption).trigger('change');
如果是选取若⼲个可以传递⼀个数组给val⽅法。如果需要对待加⼊项是否已经存在做出判断的话可以这么做:
if ($('#testselect').find('option[value='+data.id+']').length){
$('#testselect').val(data.id).trigger('change'); //如果已经存在则不添加⽽是选择那⼀项
}
else{
var newOption = new Option(data.,true,true);
$('#testselect').append(newOption).trigger('change');
}
■  动态搜索下拉菜单
所谓动态,即每次搜索框中数据发⽣变化时,前端会向后台发送ajax请求来获取⼀些数据,把这些数据⽤于填充下拉菜单的内容。实现⽅法是在初始化select2组件的时候加⼊ajax参数,如:
$('#testselect').select2({
ajax : {
url: '/api',
dataType: 'json', //⽐较重要,没有的话返回json数据会⽆法识别,搜索失败
data: function(param){
return{
keyword: ,
searchType: 'public',
page: param.page || 1}
}
}
})
ajax参数的值是⼀个object,包括url等key。url这个肯定是要有的,指出了ajax请求发往什么地⽅。data参数是可选的,在默认情况下select2发出的请求包含了以下⼏个参数:
term  此时搜索框中的内容
q  和term内容⼀样
_type  通常是query,如果涉及到结果分页时可能不⼀样
page  当有结果分页时有此参数,指出当前分页
*关于分页和page参数:在当前处于默认第⼀页的时候,发送的请求不带page参数,所以⼀般来说我们都会在data参数的函数对象中对page参数做这样⼀个处理: params.page = params.page || 1;来
保证第⼀次打开输⼊框时也会给出page=1作为请求参数。
在设置data参数之后,data参数的值是⼀个获取当前搜索框中对象(具体搜索内容是其term参数)并返回⼀个object作为ajax参数的函数对象,我们可以借此来定义⼀些⾃定义的请求参数字段。
需要特别说明的是,这⾥的ajax请求默认是get⽅法,⽬前还没到如何改成post的办法。
因为前端会⾃动对后端传递过来的数据进⾏适应select2组件的渲染,所以其对于数据的格式肯定是有要求的。具体的要求是这样的:
{
results: [
{id: '10001', text: 'Option_1'},
{id: '10002', text: 'Option_2'},
//等等,这部分就是主要的数据
],
pagination: {
more: true}
}
主要数据部分每个列表项都是⼀个object且包含id和text两个字段分别⽤来填充option标签对应的那两个字段。pagination则是指出了前端会对上送的结果做⼀个分页处理,即⼀次性只在下拉列表中显⽰有限个项,但在最下⽅有⼀个“显⽰更多项”,当滚动条到最下⽅时再⾃动发送请求去调取下⼀个分页的数据。当然,顺利地实现分页需要前端发出的ajax请求中带有param.page这个信息(如上上⾯的代码所⽰),然后后端也要根据上送上来的page的值来进⾏相应数据段的返回。前后端协调了才可以给出⽐较好的分页效果。
上⾯的说明中可以看得出对数据格式要求⽐较严格(results,pagination,id,text等字段都不能⾃定义),为了适应更加多样化的形式的数据,我们可以在ajax参数中再加上⼀个processResults字段:
$('#testselect').select2({
ajax: {
url: '/api',
dataType: 'json',
data: function(param){
return{
kw: ,
page: param.page || 1
};
},
processResults: function(data){
return{
results: data.items
};
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。