关键代码如下所示:
这种 typeahead自动补全不是bootstrap常用的typeahead.js。 以下是typeahead.js代码(如果有bootstrap3-typeahead.js更好)
Highlighter = this.options.Highlighter || this.Highlighter;
this.lookup = this.options.lookup || this.lookup;
this.matcher = this.options.matcher || this.matcher;
this.render = this.options.render || this.render;
this.select = this.options.select || this.select;
this.sorter = this.options.sorter || this.sorter;
this.source = this.options.source || this.source;
if (!this.source.length) {
var ajax = this.options.ajax;
if (typeof ajax === 'string') {
this.ajax = $.extend({},$.fn.typeahead.defaults.ajax,{ url: ajax });
} else {
this.ajax = $.extend({},ajax);
}
if (!this.ajax.url) {
this.ajax = null;
}
}
this.listen();
}
Typeahead.prototype = {
constructor: Typeahead,//=============================================================================================================
//
// Utils
//
//=============================================================================================================
//------------------------------------------------------------------
//
// Check if an event is supported by the browser eg. 'keypress'
// * This was included to handle the "exhaustive deprecation" of jQuery.browser in jQuery 1.8
//
eventSupported: function (eventName) {
var isSupported = (eventName in this.$element);
if (!isSupported) {
this.$element.setAttribute(eventName,'return;');
isSupported = typeof this.$element[eventName] === 'function';
}
return isSupported;
},//=============================================================================================================
//
// AJAX
//
//=============================================================================================================
//------------------------------------------------------------------
//
// Handle AJAX source
//
ajaxer: function () {
var that = this,query = that.$element.val();
if (query === that.query) {
return that;
}
// Query changed
that.query = query;
// Cancel last timer if set
if (that.ajax.timerId) {
clearTimeout(that.ajax.timerId);
that.ajax.timerId = null;
}
if (!query || query.length < that.ajax.triggerLength) {
// Cancel the ajax callback if in progress
if (that.ajax.xhr) {
that.ajax.xhr.abort();
that.ajax.xhr = null;
that.ajaxToggleLoadClass(false);
}
return that.shown ? that.hide() : that;
}
// Query is good to send,set a timer
that.ajax.timerId = setTimeout(function () {
$.proxy(that.ajaxExecute(query),that)
},that.ajax.timeout);
return that;
},//------------------------------------------------------------------
//
// Execute an AJAX request
//
ajaxExecute: function (query) {
this.ajaxToggleLoadClass(true);
// Cancel last call if already in progress
if (this.ajax.xhr) this.ajax.xhr.abort();
var params = this.ajax.preDispatch ? this.ajax.preDispatch(query) : { query: query };
var jAjax = (this.ajax.method === "post") ? $.post : $.get;
this.ajax.xhr = jAjax(this.ajax.url,params,$.proxy(this.ajaxLookup,this));
this.ajax.timerId = null;
},//------------------------------------------------------------------
//
// Perform a lookup in the AJAX results
//
ajaxLookup: function (data) {
var items;
this.ajaxToggleLoadClass(false);
if (!this.ajax.xhr) return;
if (this.ajax.preProcess) {
data = this.ajax.preProcess(data);
}
// Save for selection retreival
this.ajax.data = data;
items = this.grepper(this.ajax.data);
if (!items || !items.length) {
return this.shown ? this.hide() : this;
}
this.ajax.xhr = null;
return this.render(items.slice(0,this.options.items)).show();
},//------------------------------------------------------------------
//
// Toggle the loading class
//
ajaxToggleLoadClass: function (enable) {
if (!this.ajax.loadingClass) return;
this.$element.toggleClass(this.ajax.loadingClass,enable);
},//=============================================================================================================
//
// Data manipulation
//
//=============================================================================================================
//------------------------------------------------------------------
//
// Search source
//
lookup: function (event) {
var that = this,items;
if (that.ajax) {
that.ajaxer();
}
else {
that.query = that.$element.val();
if (!that.query) {
return that.shown ? that.hide() : that;
}
items = that.grepper(that.source);
if (!items || !items.length) {
return that.shown ? that.hide() : that;
}
return that.render(items.slice(0,that.options.items)).show();
}
},//------------------------------------------------------------------
//
// Filters relevent results
//
grepper: function (data) {
var that = this,items;
if (data && data.length && !data[0].hasOwnProperty(that.options.display)) {
return null;
}
items = $.grep(data,function (item) {
return that.matcher(item[that.options.display],item);
});
return this.sorter(items);
},//------------------------------------------------------------------
//
// Looks for a match in the source
//
matcher: function (item) {
return ~item.toLowerCase().indexOf(this.query.toLowerCase());
},//------------------------------------------------------------------
//
// Sorts the results
//
sorter: function (items) {
var that = this,beginswith = [],caseSensitive = [],caseInsensitive = [],item;
while (item = items.shift()) {
if (!item[that.options.display].toLowerCase().indexOf(this.query.toLowerCase())) {
beginswith.push(item);
}
else if (~item[that.options.display].indexOf(this.query)) {
caseSensitive.push(item);
}
else {
caseInsensitive.push(item);
}
}
return beginswith.concat(caseSensitive,caseInsensitive);
},//=============================================================================================================
//
// DOM manipulation
//
//=============================================================================================================
//------------------------------------------------------------------
//
// Shows the results list
//
show: function () {
var pos = $.extend({},this.$element.offset(),{
height: this.$element[0].offsetHeight
});
this.$menu.css({
top: pos.top + pos.height,left: pos.left
});
this.$menu.show();
this.shown = true;
return this;
},//------------------------------------------------------------------
//
// Hides the results list
//
hide: function () {
this.$menu.hide();
this.shown = false;
return this;
},//------------------------------------------------------------------
//
// Highlights the match(es) within the results
//
Highlighter: function (item) {
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,'\\$&');
return item.replace(new RegExp('(' + query + ')','ig'),function ($1,match) {
return '
' + match + '
'; }); },//------------------------------------------------------------------ // // Renders the results list // render: function (items) { var that = this; items = $(items).map(function (i,item) { i = $(that.options.item).attr('data-value',item[that.options.val]); i.find('a').html(that.Highlighter(item[that.options.display],item)); return i[0]; }); items.first().addClass('active'); this.$menu.html(items); return this; },//------------------------------------------------------------------ // // Item is selected // select: function () { var $selectedItem = this.$menu.find('.active'); this.$element.val($selectedItem.text()).change(); this.options.itemSelected($selectedItem,$selectedItem.attr('data-value'),$selectedItem.text()); return this.hide(); },//------------------------------------------------------------------ // // Selects the next result // next: function (event) { var active = this.$menu.find('.active').removeClass('active'); var next = active.next(); if (!next.length) { next = $(this.$menu.find('li')[0]); } next.addClass('active'); },//------------------------------------------------------------------ // // Selects the prevIoUs result // prev: function (event) { var active = this.$menu.find('.active').removeClass('active'); var prev = active.prev(); if (!prev.length) { prev = this.$menu.find('li').last(); } prev.addClass('active'); },//============================================================================================================= // // Events // //============================================================================================================= //------------------------------------------------------------------ // // Listens for user events // listen: function () { this.$element.on('blur',$.proxy(this.blur,this)) .on('keyup',$.proxy(this.keyup,this)); if (this.eventSupported('keydown')) { this.$element.on('keydown',$.proxy(this.keypress,this)); } else { this.$element.on('keypress',this)); } this.$menu.on('click',$.proxy(this.click,this)) .on('mouseenter','li',$.proxy(this.mouseenter,this)); },//------------------------------------------------------------------ // // Handles a key being raised up // keyup: function (e) { e.stopPropagation(); e.preventDefault(); switch (e.keyCode) { case 40: // down arrow case 38: // up arrow break; case 9: // tab case 13: // enter if (!this.shown) { return; } this.select(); break; case 27: // escape this.hide(); break; default: this.lookup(); } },//------------------------------------------------------------------ // // Handles a key being pressed // keypress: function (e) { e.stopPropagation(); if (!this.shown) { return; } switch (e.keyCode) { case 9: // tab case 13: // enter case 27: // escape e.preventDefault(); break; case 38: // up arrow e.preventDefault(); this.prev(); break; case 40: // down arrow e.preventDefault(); this.next(); break; } },//------------------------------------------------------------------ // // Handles cursor exiting the textBox // blur: function (e) { var that = this; e.stopPropagation(); e.preventDefault(); setTimeout(function () { if (!that.$menu.is(':focus')) { that.hide(); } },150) },//------------------------------------------------------------------ // // Handles clicking on the results list // click: function (e) { e.stopPropagation(); e.preventDefault(); this.select(); },//------------------------------------------------------------------ // // Handles the mouse entering the results list // mouseenter: function (e) { this.$menu.find('.active').removeClass('active'); $(e.currentTarget).addClass('active'); } } //------------------------------------------------------------------ // // Plugin definition // $.fn.typeahead = function (option) { return this.each(function () { var $this = $(this),data = $this.data('typeahead'),options = typeof option === 'object' && option; if (!data) { $this.data('typeahead',(data = new Typeahead(this,options))); } if (typeof option === 'string') { data[option](); } }); } //------------------------------------------------------------------ // // Defaults // $.fn.typeahead.defaults = { source: [],items: 8,menu: '以上所述是小编给大家介绍的BootStrap Typeahead自动补全插件实例代码 。编程之家 jb51.cc 收集整理的教程希望能对你有所帮助,如果觉得编程之家不错,可分享给好友!感谢支持。