| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  | /* ============================================================= | 
					
						
							|  |  |  |  * bootstrap-typeahead.js v2.0.0 | 
					
						
							| 
									
										
										
										
											2012-01-25 03:08:03 +08:00
										 |  |  |  * http://twitter.github.com/bootstrap/javascript.html#typeahead
 | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |  * ============================================================= | 
					
						
							| 
									
										
										
										
											2012-01-15 15:28:48 +08:00
										 |  |  |  * Copyright 2012 Twitter, Inc. | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  * ============================================================ */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | !function( $ ){ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   "use strict" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var Typeahead = function ( element, options ) { | 
					
						
							|  |  |  |     this.$element = $(element) | 
					
						
							|  |  |  |     this.options = $.extend({}, $.fn.typeahead.defaults, options) | 
					
						
							| 
									
										
										
										
											2012-01-29 05:16:05 +08:00
										 |  |  |     this.matcher = this.options.matcher || this.matcher | 
					
						
							|  |  |  |     this.sorter = this.options.sorter || this.sorter | 
					
						
							|  |  |  |     this.highlighter = this.options.highlighter || this.highlighter | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |     this.$menu = $(this.options.menu).appendTo('body') | 
					
						
							| 
									
										
										
										
											2012-01-27 15:16:02 +08:00
										 |  |  |     this.source = this.options.source | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |     this.shown = false | 
					
						
							|  |  |  |     this.listen() | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Typeahead.prototype = { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor: Typeahead | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |   , select: function () { | 
					
						
							|  |  |  |       var val = this.$menu.find('.active').attr('data-value') | 
					
						
							|  |  |  |       this.$element.val(val) | 
					
						
							|  |  |  |       return this.hide() | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   , show: function () { | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |       var pos = $.extend({}, this.$element.offset(), { | 
					
						
							|  |  |  |         height: this.$element[0].offsetHeight | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this.$menu.css({ | 
					
						
							|  |  |  |         top: pos.top + pos.height | 
					
						
							|  |  |  |       , left: pos.left | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |       this.$menu.show() | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |       this.shown = true | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |       return this | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   , hide: function () { | 
					
						
							|  |  |  |       this.$menu.hide() | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |       this.shown = false | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |       return this | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   , lookup: function (event) { | 
					
						
							| 
									
										
										
										
											2012-01-22 14:06:36 +08:00
										 |  |  |       var that = this | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |         , items | 
					
						
							| 
									
										
										
										
											2012-01-22 14:06:36 +08:00
										 |  |  |         , q | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this.query = this.$element.val() | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-22 14:06:36 +08:00
										 |  |  |       if (!this.query) { | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |         return this.shown ? this.hide() : this | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-28 14:27:06 +08:00
										 |  |  |       items = $.grep(this.source, function (item) { | 
					
						
							|  |  |  |         if (that.matcher(item)) return item | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |       }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-28 14:27:06 +08:00
										 |  |  |       items = this.sorter(items) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |       if (!items.length) { | 
					
						
							|  |  |  |         return this.shown ? this.hide() : this | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |       return this.render(items.slice(0, this.options.items)).show() | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-29 05:16:05 +08:00
										 |  |  |   , matcher: function (item) { | 
					
						
							|  |  |  |       return ~item.toLowerCase().indexOf(this.query.toLowerCase()) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   , sorter: function (items) { | 
					
						
							|  |  |  |       var beginswith = [] | 
					
						
							|  |  |  |         , caseSensitive = [] | 
					
						
							|  |  |  |         , caseInsensitive = [] | 
					
						
							|  |  |  |         , item | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       while (item = items.shift()) { | 
					
						
							|  |  |  |         if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item) | 
					
						
							|  |  |  |         else if (~item.indexOf(this.query)) caseSensitive.push(item) | 
					
						
							|  |  |  |         else caseInsensitive.push(item) | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return beginswith.concat(caseSensitive, caseInsensitive) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   , highlighter: function (item) { | 
					
						
							|  |  |  |       return item.replace(new RegExp('(' + this.query + ')', 'ig'), function ($1, match) { | 
					
						
							|  |  |  |         return '<strong>' + match + '</strong>' | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |   , render: function (items) { | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |       var that = this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       items = $(items).map(function (i, item) { | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |         i = $(that.options.item).attr('data-value', item) | 
					
						
							| 
									
										
										
										
											2012-01-29 05:16:05 +08:00
										 |  |  |         i.find('a').html(that.highlighter(item)) | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |         return i[0] | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |       }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       items.first().addClass('active') | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |       this.$menu.html(items) | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |       return this | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   , next: function (event) { | 
					
						
							|  |  |  |       var active = this.$menu.find('.active').removeClass('active') | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |         , next = active.next() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!next.length) { | 
					
						
							|  |  |  |         next = $(this.$menu.find('li')[0]) | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       next.addClass('active') | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   , prev: function (event) { | 
					
						
							|  |  |  |       var active = this.$menu.find('.active').removeClass('active') | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |         , prev = active.prev() | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |       if (!prev.length) { | 
					
						
							|  |  |  |         prev = this.$menu.find('li').last() | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       prev.addClass('active') | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-22 14:06:36 +08:00
										 |  |  |   , listen: function () { | 
					
						
							|  |  |  |       this.$element | 
					
						
							|  |  |  |         .on('blur',     $.proxy(this.blur, this)) | 
					
						
							|  |  |  |         .on('keypress', $.proxy(this.keypress, this)) | 
					
						
							|  |  |  |         .on('keyup',    $.proxy(this.keyup, this)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if ($.browser.webkit || $.browser.msie) { | 
					
						
							|  |  |  |         this.$element.on('keydown', $.proxy(this.keypress, this)) | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       this.$menu | 
					
						
							|  |  |  |         .on('click', $.proxy(this.click, this)) | 
					
						
							|  |  |  |         .on('mouseenter', 'li', $.proxy(this.mouseenter, this)) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |   , keyup: function (e) { | 
					
						
							|  |  |  |       e.stopPropagation() | 
					
						
							|  |  |  |       e.preventDefault() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       switch(e.keyCode) { | 
					
						
							|  |  |  |         case 40: // down arrow
 | 
					
						
							|  |  |  |         case 38: // up arrow
 | 
					
						
							|  |  |  |           break | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         case 9: // tab
 | 
					
						
							|  |  |  |         case 13: // enter
 | 
					
						
							| 
									
										
										
										
											2012-01-27 07:23:09 +08:00
										 |  |  |           if (!this.shown) return | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |           this.select() | 
					
						
							|  |  |  |           break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case 27: // escape
 | 
					
						
							|  |  |  |           this.hide() | 
					
						
							|  |  |  |           break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |           this.lookup() | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |   , keypress: function (e) { | 
					
						
							|  |  |  |       e.stopPropagation() | 
					
						
							| 
									
										
										
										
											2012-01-27 07:23:09 +08:00
										 |  |  |       if (!this.shown) return | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       switch(e.keyCode) { | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |         case 9: // tab
 | 
					
						
							|  |  |  |         case 13: // enter
 | 
					
						
							|  |  |  |         case 27: // escape
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |           e.preventDefault() | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |           break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case 38: // up arrow
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |           e.preventDefault() | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |           this.prev() | 
					
						
							|  |  |  |           break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case 40: // down arrow
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |           e.preventDefault() | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |           this.next() | 
					
						
							|  |  |  |           break | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   , blur: function (e) { | 
					
						
							|  |  |  |       var that = this | 
					
						
							|  |  |  |       e.stopPropagation() | 
					
						
							|  |  |  |       e.preventDefault() | 
					
						
							|  |  |  |       setTimeout(function () { that.hide() }, 150) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   , click: function (e) { | 
					
						
							|  |  |  |       e.stopPropagation() | 
					
						
							|  |  |  |       e.preventDefault() | 
					
						
							|  |  |  |       this.select() | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   , mouseenter: function (e) { | 
					
						
							|  |  |  |       this.$menu.find('.active').removeClass('active') | 
					
						
							|  |  |  |       $(e.currentTarget).addClass('active') | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |   /* TYPEAHEAD PLUGIN DEFINITION | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |    * =========================== */ | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   $.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]() | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   $.fn.typeahead.defaults = { | 
					
						
							| 
									
										
										
										
											2012-01-27 15:16:02 +08:00
										 |  |  |     source: [] | 
					
						
							|  |  |  |   , items: 8 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  |   , menu: '<ul class="typeahead dropdown-menu"></ul>' | 
					
						
							|  |  |  |   , item: '<li><a href="#"></a></li>' | 
					
						
							| 
									
										
										
										
											2012-01-07 10:30:32 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   $.fn.typeahead.Constructor = Typeahead | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-08 16:49:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |  /* TYPEAHEAD DATA-API | 
					
						
							|  |  |  |   * ================== */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   $(function () { | 
					
						
							|  |  |  |     $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) { | 
					
						
							|  |  |  |       var $this = $(this) | 
					
						
							|  |  |  |       if ($this.data('typeahead')) return | 
					
						
							|  |  |  |       e.preventDefault() | 
					
						
							|  |  |  |       $this.typeahead($this.data()) | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |   }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-27 06:07:06 +08:00
										 |  |  | }( window.jQuery ) |