/** Typeahead input (bootstrap only). Based on Twitter Bootstrap [typeahead](http://twitter.github.com/bootstrap/javascript.html#typeahead). Depending on `source` format typeahead operates in two modes: * **strings**: When `source` defined as array of strings, e.g. `['text1', 'text2', 'text3' ...]`. User can submit one of these strings or any text entered in input (even if it is not matching source). * **objects**: When `source` defined as array of objects, e.g. `[{value: 1, text: "text1"}, {value: 2, text: "text2"}, ...]`. User can submit only values that are in source (otherwise `null` is submitted). This is more like *dropdown* behavior. @class typeahead @extends list @since 1.4.1 @final @example **/ (function ($) { "use strict"; var Constructor = function (options) { this.init('typeahead', options, Constructor.defaults); //overriding objects in config (as by default jQuery extend() is not recursive) this.options.typeahead = $.extend({}, Constructor.defaults.typeahead, { //set default methods for typeahead to work with objects matcher: this.matcher, sorter: this.sorter, highlighter: this.highlighter, updater: this.updater }, options.typeahead); }; $.fn.editableutils.inherit(Constructor, $.fn.editabletypes.list); $.extend(Constructor.prototype, { renderList: function() { this.$input = this.$tpl.is('input') ? this.$tpl : this.$tpl.find('input[type="text"]'); //set source of typeahead this.options.typeahead.source = this.sourceData; //apply typeahead this.$input.typeahead(this.options.typeahead); //patch some methods in typeahead var ta = this.$input.data('typeahead'); ta.render = $.proxy(this.typeaheadRender, ta); ta.select = $.proxy(this.typeaheadSelect, ta); ta.move = $.proxy(this.typeaheadMove, ta); this.renderClear(); this.setClass(); this.setAttr('placeholder'); }, value2htmlFinal: function(value, element) { if(this.getIsObjects()) { var items = $.fn.editableutils.itemsByValue(value, this.sourceData); $(element).text(items.length ? items[0].text : ''); } else { $(element).text(value); } }, html2value: function (html) { return html ? html : null; }, value2input: function(value) { if(this.getIsObjects()) { var items = $.fn.editableutils.itemsByValue(value, this.sourceData); this.$input.data('value', value).val(items.length ? items[0].text : ''); } else { this.$input.val(value); } }, input2value: function() { if(this.getIsObjects()) { var value = this.$input.data('value'), items = $.fn.editableutils.itemsByValue(value, this.sourceData); if(items.length && items[0].text.toLowerCase() === this.$input.val().toLowerCase()) { return value; } else { return null; //entered string not found in source } } else { return this.$input.val(); } }, /* if in sourceData values <> texts, typeahead in "objects" mode: user must pick some value from list, otherwise `null` returned. if all values == texts put typeahead in "strings" mode: anything what entered is submited. */ getIsObjects: function() { if(this.isObjects === undefined) { this.isObjects = false; for(var i=0; i **/ tpl:'', /** Configuration of typeahead. [Full list of options](http://twitter.github.com/bootstrap/javascript.html#typeahead). @property typeahead @type object @default null **/ typeahead: null, /** Whether to show `clear` button @property clear @type boolean @default true **/ clear: true }); $.fn.editabletypes.typeahead = Constructor; }(window.jQuery));