Mercurial > p > roundup > code
view 3rdparty/bootstrap/js/bootstrap-typeahead.js @ 5695:3e1b66c4e1e2
Update docs. Correct errors reported by setup.py build_docs. Add rest
interface and link to rest doc to features page. Add link to xmlrpc
doc to features page. Add rest doc to index. Update rest doc,
hopefully clarify confusing use of parameters in patch action
section. Fix code examples in "Adding new rest endpoints" section. Fix
example adding import of exception.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sun, 07 Apr 2019 20:17:52 -0400 |
| parents | c109f7c1e477 |
| children |
line wrap: on
line source
/* ============================================================= * bootstrap-typeahead.js v2.2.2 * http://twitter.github.com/bootstrap/javascript.html#typeahead * ============================================================= * Copyright 2012 Twitter, Inc. * * 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"; // jshint ;_; /* TYPEAHEAD PUBLIC CLASS DEFINITION * ================================= */ var Typeahead = function (element, options) { this.$element = $(element) this.options = $.extend({}, $.fn.typeahead.defaults, options) this.matcher = this.options.matcher || this.matcher this.sorter = this.options.sorter || this.sorter this.highlighter = this.options.highlighter || this.highlighter this.updater = this.options.updater || this.updater this.source = this.options.source this.$menu = $(this.options.menu) this.shown = false this.listen() } Typeahead.prototype = { constructor: Typeahead , select: function () { var val = this.$menu.find('.active').attr('data-value') this.$element .val(this.updater(val)) .change() return this.hide() } , updater: function (item) { return item } , show: function () { var pos = $.extend({}, this.$element.position(), { height: this.$element[0].offsetHeight }) this.$menu .insertAfter(this.$element) .css({ top: pos.top + pos.height , left: pos.left }) .show() this.shown = true return this } , hide: function () { this.$menu.hide() this.shown = false return this } , lookup: function (event) { var items this.query = this.$element.val() if (!this.query || this.query.length < this.options.minLength) { return this.shown ? this.hide() : this } items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source return items ? this.process(items) : this } , process: function (items) { var that = this items = $.grep(items, function (item) { return that.matcher(item) }) items = this.sorter(items) if (!items.length) { return this.shown ? this.hide() : this } return this.render(items.slice(0, this.options.items)).show() } , 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) { var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&') return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) { return '<strong>' + match + '</strong>' }) } , render: function (items) { var that = this items = $(items).map(function (i, item) { i = $(that.options.item).attr('data-value', item) i.find('a').html(that.highlighter(item)) return i[0] }) items.first().addClass('active') this.$menu.html(items) return this } , next: function (event) { var active = this.$menu.find('.active').removeClass('active') , next = active.next() if (!next.length) { next = $(this.$menu.find('li')[0]) } next.addClass('active') } , prev: function (event) { var active = this.$menu.find('.active').removeClass('active') , prev = active.prev() if (!prev.length) { prev = this.$menu.find('li').last() } prev.addClass('active') } , listen: function () { this.$element .on('blur', $.proxy(this.blur, this)) .on('keypress', $.proxy(this.keypress, this)) .on('keyup', $.proxy(this.keyup, this)) if (this.eventSupported('keydown')) { this.$element.on('keydown', $.proxy(this.keydown, this)) } this.$menu .on('click', $.proxy(this.click, this)) .on('mouseenter', 'li', $.proxy(this.mouseenter, this)) } , eventSupported: function(eventName) { var isSupported = eventName in this.$element if (!isSupported) { this.$element.setAttribute(eventName, 'return;') isSupported = typeof this.$element[eventName] === 'function' } return isSupported } , move: function (e) { 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 } e.stopPropagation() } , keydown: function (e) { this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27]) this.move(e) } , keypress: function (e) { if (this.suppressKeyPressRepeat) return this.move(e) } , keyup: function (e) { switch(e.keyCode) { case 40: // down arrow case 38: // up arrow case 16: // shift case 17: // ctrl case 18: // alt break case 9: // tab case 13: // enter if (!this.shown) return this.select() break case 27: // escape if (!this.shown) return this.hide() break default: this.lookup() } e.stopPropagation() e.preventDefault() } , blur: function (e) { var that = this 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') } } /* TYPEAHEAD PLUGIN DEFINITION * =========================== */ var old = $.fn.typeahead $.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 = { source: [] , items: 8 , menu: '<ul class="typeahead dropdown-menu"></ul>' , item: '<li><a href="#"></a></li>' , minLength: 1 } $.fn.typeahead.Constructor = Typeahead /* TYPEAHEAD NO CONFLICT * =================== */ $.fn.typeahead.noConflict = function () { $.fn.typeahead = old return this } /* TYPEAHEAD DATA-API * ================== */ $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) { var $this = $(this) if ($this.data('typeahead')) return e.preventDefault() $this.typeahead($this.data()) }) }(window.jQuery);
