前戏
原cn域名已经很久不续费了,现在打算用hisune.com来继续写博客,之前的博客日志就不保留了,直接弄新的,内容全部原创不追求访问量,纯粹为了提升自身技术。
最近要用到ajax的带下拉菜单的搜索功能,原本项目使用的是multiselect,看了一下api文档,没有ajax功能,于是谷歌了一番,也没有现成的解决办法,但找到一个插件,https://github.com/truckingsim/Ajax-Bootstrap-Select
下载下来后试用了一下,放弃了,原因有以下几点:
- 原本项目使用multiselect,这个插件基于bootstrap-select插件,且试了一下,不支持multiselect;
- 如果格外使用bootstrap-select插件,为了这个功能得加多两个插件,不划算;
- 插件对中文支持不好;
- 由于基于bootstrap-select,不支持多选
解决
于是去multiselect的git项目出发了个question,隔日后没有收到解决办法,决定自己动手了。先更新了multiselect插件到最新版本,然后大概看了一下代码开始动工:
- 在
Multiselect.prototype
的default
里面新增一个参数:ajaxUrl: '',
-
buildFilter
函数中加入判断:if (this.query !== event.target.value) { this.query = event.target.value; if(this.options.ajaxUrl != ''){ var _t = this; $.ajax({ type: 'POST', data: {name: event.target.value}, url: this.options.ajaxUrl, timeout: 20000, dataType: "json", success: function(json){ var _option = ''; $.each(json, function(i, n){ _option += '' + n + ''; }); _t.$select.html(_option); _t.$ul.find('li:not(.filter)').remove(); // 清空除搜索框外的li _t.buildSelectAll(); _t.buildDropdownOptions(); _t.updateButtonText(); _t.updateSelectAll(); _t.$filter.find('input').focus(); } }); }else{ $.each($('li', this.$ul), $.proxy(function(index, element) { var value = $('input', element).val(); var text = $('label', element).text(); var filterCandidate = ''; if ((this.options.filterBehavior === 'text')) { filterCandidate = text; } else if ((this.options.filterBehavior === 'value')) { filterCandidate = value; } else if (this.options.filterBehavior === 'both') { filterCandidate = text + 'n' + value; } if (value !== this.options.selectAllValue && text) { // by default lets assume that element is not // interesting for this search var showElement = false; if (this.options.enableCaseInsensitiveFiltering && filterCandidate.toLowerCase().indexOf(this.query.toLowerCase()) > -1) { showElement = true; } else if (filterCandidate.indexOf(this.query) > -1) { showElement = true; } if (showElement) { $(element).show().removeClass("filter-hidden"); } else { $(element).hide().addClass("filter-hidden"); } } }, this)); } }
为什么ajax返回后不直接用
rebuild
?由于使用rebuild
后,每次输入,下拉select都会还原,search的input框在每次输入后会清空。如果_t.$filter.find('input').val(_t.query);
这样在英文输入法下是OK的,但中文输入法下,例如输入:"测试",会变成"ceshi测试"。 - 为了防止输入其他非可见数字字母键也进行查询,在buildFilter函数的
.on('input onkeyup', $.proxy(function(event) {
下加入:var specialKeyCodeMap = { 9: "tab", 13: "enter", 16: "shift", 17: "ctrl", 18: "alt", 27: "esc", 37: "left", 39: "right", 38: "up", 40: "down", 229: "unknown" //Returned if it can't get the virtual key number per w3 spec: http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html }; if(specialKeyCodeMap[event.keyCode]){ return true; }
这个是参考了
Ajax-Bootstrap-Select
的代码。 - 8月28日补充,修复一个小bug:
$('li input', this.$ul).on('change', $.proxy(function(event) {
改为:
$('li input:not([type=text])', this.$ul).on('change', $.proxy(function(event) {
防止change绑定到了搜索框的input
- 8月28日补充,multiselect在ie8下搜索是无效的,只支持ie9+,修复方法:
this.$filter.val(this.query).on('click', function(event) { event.stopPropagation(); }).on('input onkeyup', $.proxy(function(event) {
改为:
this.$filter.val(this.query).on('click', function(event) { event.stopPropagation(); }).on('input keyup', $.proxy(function(event) {
最后关于服务端的返回:返回的数据必须是json格式,key为option的name,value为option的value
至此,搞定!
如果您觉得您在我这里学到了新姿势,博主支持转载,姿势本身就是用来相互学习的。同时,本站文章如未注明均为 hisune 原创 请尊重劳动成果 转载请注明 转自: 为bootstrap的multiselect插件增加ajax搜索功能 - hisune.com
0 Comments