From bf9d8fcc070fa826c342282e102fe00e1af76d10 Mon Sep 17 00:00:00 2001 From: Matt Morgan Date: Thu, 26 Apr 2012 14:09:20 -0400 Subject: [PATCH] Alter typeahead to accept synchronous/asynchronous data source via function/callback --- docs/templates/pages/javascript.mustache | 6 ++-- js/bootstrap-typeahead.js | 16 +++++++---- js/tests/unit/bootstrap-typeahead.js | 36 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/docs/templates/pages/javascript.mustache b/docs/templates/pages/javascript.mustache index 1ae3ffa5a8..e6f1576890 100644 --- a/docs/templates/pages/javascript.mustache +++ b/docs/templates/pages/javascript.mustache @@ -1385,9 +1385,9 @@ $('.carousel').carousel({ {{_i}}source{{/i}} - {{_i}}array{{/i}} + {{_i}}array, function{{/i}} [ ] - {{_i}}The data source to query against.{{/i}} + {{_i}}The data source to query against. May be an array of strings or a function. The function is passed two arguments, the query value in the input field and the process callback. The function may be used synchronously by returning the data source directly or asynchronously via the process callback's single argument.{{/i}} {{_i}}items{{/i}} @@ -1426,4 +1426,4 @@ $('.carousel').carousel({

{{_i}}Initializes an input with a typeahead.{{/i}}

- \ No newline at end of file + diff --git a/js/bootstrap-typeahead.js b/js/bootstrap-typeahead.js index 95a0fcdb78..281bdd6b3e 100644 --- a/js/bootstrap-typeahead.js +++ b/js/bootstrap-typeahead.js @@ -77,9 +77,7 @@ } , lookup: function (event) { - var that = this - , items - , q + var items this.query = this.$element.val() @@ -87,7 +85,15 @@ return this.shown ? this.hide() : this } - items = $.grep(this.source, function (item) { + 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) }) @@ -282,4 +288,4 @@ }) }) -}(window.jQuery); \ No newline at end of file +}(window.jQuery); diff --git a/js/tests/unit/bootstrap-typeahead.js b/js/tests/unit/bootstrap-typeahead.js index 4e2428d6a4..25d4cafd8e 100644 --- a/js/tests/unit/bootstrap-typeahead.js +++ b/js/tests/unit/bootstrap-typeahead.js @@ -52,6 +52,42 @@ $(function () { typeahead.$menu.remove() }) + test("should accept data source via synchronous function", function () { + var $input = $('').typeahead({ + source: function () { + return ['aa', 'ab', 'ac'] + } + }) + , typeahead = $input.data('typeahead') + + $input.val('a') + typeahead.lookup() + + ok(typeahead.$menu.is(":visible"), 'typeahead is visible') + equals(typeahead.$menu.find('li').length, 3, 'has 3 items in menu') + equals(typeahead.$menu.find('.active').length, 1, 'one item is active') + + typeahead.$menu.remove() + }) + + test("should accept data source via asynchronous function", function () { + var $input = $('').typeahead({ + source: function (query, process) { + process(['aa', 'ab', 'ac']) + } + }) + , typeahead = $input.data('typeahead') + + $input.val('a') + typeahead.lookup() + + ok(typeahead.$menu.is(":visible"), 'typeahead is visible') + equals(typeahead.$menu.find('li').length, 3, 'has 3 items in menu') + equals(typeahead.$menu.find('.active').length, 1, 'one item is active') + + typeahead.$menu.remove() + }) + test("should not explode when regex chars are entered", function () { var $input = $('').typeahead({ source: ['aa', 'ab', 'ac', 'mdo*', 'fat+']