first commit
This commit is contained in:
@@ -0,0 +1,277 @@
|
||||
Bloodhound
|
||||
==========
|
||||
|
||||
Bloodhound is the typeahead.js suggestion engine. Bloodhound is robust,
|
||||
flexible, and offers advanced functionalities such as prefetching, intelligent
|
||||
caching, fast lookups, and backfilling with remote data.
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
|
||||
* [Features](#features)
|
||||
* [Usage](#usage)
|
||||
* [API](#api)
|
||||
* [Options](#options)
|
||||
* [Prefetch](#prefetch)
|
||||
* [Remote](#remote)
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Works with hardcoded data
|
||||
* Prefetches data on initialization to reduce suggestion latency
|
||||
* Uses local storage intelligently to cut down on network requests
|
||||
* Backfills suggestions from a remote source
|
||||
* Rate-limits and caches network requests to remote sources to lighten the load
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
### API
|
||||
|
||||
* [`new Bloodhound(options)`](#new-bloodhoundoptions)
|
||||
* [`Bloodhound.noConflict()`](#bloodhoundnoconflict)
|
||||
* [`Bloodhound#initialize(reinitialize)`](#bloodhoundinitializereinitialize)
|
||||
* [`Bloodhound#add(data)`](#bloodhoundadddata)
|
||||
* [`Bloodhound#get(ids)`](#bloodhoundgetids)
|
||||
* [`Bloodhound#search(query, sync, async)`](#bloodhoundsearchquery-sync-async)
|
||||
* [`Bloodhound#clear()`](#bloodhoundclear)
|
||||
|
||||
#### new Bloodhound(options)
|
||||
|
||||
The constructor function. It takes an [options hash](#options) as its only
|
||||
argument.
|
||||
|
||||
```javascript
|
||||
var engine = new Bloodhound({
|
||||
local: ['dog', 'pig', 'moose'],
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
datumTokenizer: Bloodhound.tokenizers.whitespace
|
||||
});
|
||||
```
|
||||
|
||||
#### Bloodhound.noConflict()
|
||||
|
||||
Returns a reference to `Bloodhound` and reverts `window.Bloodhound` to its
|
||||
previous value. Can be used to avoid naming collisions.
|
||||
|
||||
```javascript
|
||||
var Dachshund = Bloodhound.noConflict();
|
||||
```
|
||||
|
||||
#### Bloodhound#initialize(reinitialize)
|
||||
|
||||
Kicks off the initialization of the suggestion engine. Initialization entails
|
||||
adding the data provided by `local` and `prefetch` to the internal search
|
||||
index as well as setting up transport mechanism used by `remote`. Before
|
||||
`#initialize` is called, the `#get` and `#search` methods will effectively be
|
||||
no-ops.
|
||||
|
||||
Note, unless the `initialize` option is `false`, this method is implicitly
|
||||
called by the constructor.
|
||||
|
||||
```javascript
|
||||
var engine = new Bloodhound({
|
||||
initialize: false,
|
||||
local: ['dog', 'pig', 'moose'],
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
datumTokenizer: Bloodhound.tokenizers.whitespace
|
||||
});
|
||||
|
||||
var promise = engine.initialize();
|
||||
|
||||
promise
|
||||
.done(function() { console.log('ready to go!'); })
|
||||
.fail(function() { console.log('err, something went wrong :('); });
|
||||
```
|
||||
|
||||
After initialization, how subsequent invocations of `#initialize` behave
|
||||
depends on the `reinitialize` argument. If `reinitialize` is falsy, the
|
||||
method will not execute the initialization logic and will just return the same
|
||||
jQuery promise returned by the initial invocation. If `reinitialize` is truthy,
|
||||
the method will behave as if it were being called for the first time.
|
||||
|
||||
```javascript
|
||||
var promise1 = engine.initialize();
|
||||
var promise2 = engine.initialize();
|
||||
var promise3 = engine.initialize(true);
|
||||
|
||||
assert(promise1 === promise2);
|
||||
assert(promise3 !== promise1 && promise3 !== promise2);
|
||||
```
|
||||
|
||||
<!-- section links -->
|
||||
|
||||
[jQuery promise]: http://api.jquery.com/Types/#Promise
|
||||
|
||||
#### Bloodhound#add(data)
|
||||
|
||||
Takes one argument, `data`, which is expected to be an array. The data passed
|
||||
in will get added to the internal search index.
|
||||
|
||||
```javascript
|
||||
engine.add([{ val: 'one' }, { val: 'two' }]);
|
||||
```
|
||||
|
||||
#### Bloodhound#get(ids)
|
||||
|
||||
Returns the data in the local search index corresponding to `ids`.
|
||||
|
||||
```javascript
|
||||
var engine = new Bloodhound({
|
||||
local: [{ id: 1, name: 'dog' }, { id: 2, name: 'pig' }],
|
||||
identify: function(obj) { return obj.id; },
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
datumTokenizer: Bloodhound.tokenizers.whitespace
|
||||
});
|
||||
|
||||
engine.get([1, 3]); // [{ id: 1, name: 'dog' }, null]
|
||||
```
|
||||
|
||||
#### Bloodhound#search(query, sync, async)
|
||||
|
||||
Returns the data that matches `query`. Matches found in the local search index
|
||||
will be passed to the `sync` callback. If the data passed to `sync` doesn't
|
||||
contain at least `sufficient` number of datums, `remote` data will be requested
|
||||
and then passed to the `async` callback.
|
||||
|
||||
```javascript
|
||||
bloodhound.get(myQuery, sync, async);
|
||||
|
||||
function sync(datums) {
|
||||
console.log('datums from `local`, `prefetch`, and `#add`');
|
||||
console.log(datums);
|
||||
}
|
||||
|
||||
function async(datums) {
|
||||
console.log('datums from `remote`');
|
||||
console.log(datums);
|
||||
}
|
||||
```
|
||||
|
||||
#### Bloodhound#clear()
|
||||
|
||||
Clears the internal search index that's powered by `local`, `prefetch`, and
|
||||
`#add`.
|
||||
|
||||
```javascript
|
||||
engine.clear();
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
When instantiating a Bloodhound suggestion engine, there are a number of
|
||||
options you can configure.
|
||||
|
||||
* `datumTokenizer` – A function with the signature `(datum)` that transforms a
|
||||
datum into an array of string tokens. **Required**.
|
||||
|
||||
* `queryTokenizer` – A function with the signature `(query)` that transforms a
|
||||
query into an array of string tokens. **Required**.
|
||||
|
||||
* `initialize` – If set to `false`, the Bloodhound instance will not be
|
||||
implicitly initialized by the constructor function. Defaults to `true`.
|
||||
|
||||
* `identify` – Given a datum, this function is expected to return a unique id
|
||||
for it. Defaults to `JSON.stringify`. Note that it is **highly recommended**
|
||||
to override this option.
|
||||
|
||||
* `sufficient` – If the number of datums provided from the internal search
|
||||
index is less than `sufficient`, `remote` will be used to backfill search
|
||||
requests triggered by calling `#search`. Defaults to `5`.
|
||||
|
||||
* `sorter` – A [compare function] used to sort data returned from the internal
|
||||
search index.
|
||||
|
||||
* `local` – An array of data or a function that returns an array of data. The
|
||||
data will be added to the internal search index when `#initialize` is called.
|
||||
|
||||
* `prefetch` – Can be a URL to a JSON file containing an array of data or, if
|
||||
more configurability is needed, a [prefetch options hash](#prefetch).
|
||||
|
||||
* `remote` – Can be a URL to fetch data from when the data provided by
|
||||
the internal search index is insufficient or, if more configurability is
|
||||
needed, a [remote options hash](#remote).
|
||||
|
||||
<!-- section links -->
|
||||
|
||||
[compare function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
|
||||
|
||||
### Prefetch
|
||||
|
||||
Prefetched data is fetched and processed on initialization. If the browser
|
||||
supports local storage, the processed data will be cached there to
|
||||
prevent additional network requests on subsequent page loads.
|
||||
|
||||
**WARNING:** While it's possible to get away with it for smaller data sets,
|
||||
prefetched data isn't meant to contain entire sets of data. Rather, it should
|
||||
act as a first-level cache. Ignoring this warning means you'll run the risk of
|
||||
hitting [local storage limits].
|
||||
|
||||
When configuring `prefetch`, the following options are available.
|
||||
|
||||
* `url` – The URL prefetch data should be loaded from. **Required.**
|
||||
|
||||
* `cache` – If `false`, will not attempt to read or write to local storage and
|
||||
will always load prefetch data from `url` on initialization. Defaults to
|
||||
`true`.
|
||||
|
||||
* `ttl` – The time (in milliseconds) the prefetched data should be cached in
|
||||
local storage. Defaults to `86400000` (1 day).
|
||||
|
||||
* `cacheKey` – The key that data will be stored in local storage under.
|
||||
Defaults to value of `url`.
|
||||
|
||||
* `thumbprint` – A string used for thumbprinting prefetched data. If this
|
||||
doesn't match what's stored in local storage, the data will be refetched.
|
||||
|
||||
* `prepare` – A function that provides a hook to allow you to prepare the
|
||||
settings object passed to `transport` when a request is about to be made.
|
||||
The function signature should be `prepare(settings)` where `settings` is the
|
||||
default settings object created internally by the Bloodhound instance. The
|
||||
`prepare` function should return a settings object. Defaults to the
|
||||
[identity function].
|
||||
|
||||
* `transform` – A function with the signature `transform(response)` that allows
|
||||
you to transform the prefetch response before the Bloodhound instance operates
|
||||
on it. Defaults to the [identity function].
|
||||
|
||||
<!-- section links -->
|
||||
|
||||
[local storage limits]: http://stackoverflow.com/a/2989317
|
||||
[identity function]: http://en.wikipedia.org/wiki/Identity_function
|
||||
|
||||
### Remote
|
||||
|
||||
Bloodhound only goes to the network when the internal search engine cannot
|
||||
provide a sufficient number of results. In order to prevent an obscene number
|
||||
of requests being made to the remote endpoint, requests are rate-limited.
|
||||
|
||||
When configuring `remote`, the following options are available.
|
||||
|
||||
* `url` – The URL remote data should be loaded from. **Required.**
|
||||
|
||||
* `prepare` – A function that provides a hook to allow you to prepare the
|
||||
settings object passed to `transport` when a request is about to be made.
|
||||
The function signature should be `prepare(query, settings)`, where `query` is
|
||||
the query `#search` was called with and `settings` is the default settings
|
||||
object created internally by the Bloodhound instance. The `prepare` function
|
||||
should return a settings object. Defaults to the [identity function].
|
||||
|
||||
* `wildcard` – A convenience option for `prepare`. If set, `prepare` will be a
|
||||
function that replaces the value of this option in `url` with the URI encoded
|
||||
query.
|
||||
|
||||
* `rateLimitBy` – The method used to rate-limit network requests. Can be either
|
||||
`debounce` or `throttle`. Defaults to `debounce`.
|
||||
|
||||
* `rateLimitWait` – The time interval in milliseconds that will be used by
|
||||
`rateLimitBy`. Defaults to `300`.
|
||||
|
||||
* `transform` – A function with the signature `transform(response)` that allows
|
||||
you to transform the remote response before the Bloodhound instance operates
|
||||
on it. Defaults to the [identity function].
|
||||
|
||||
<!-- section links -->
|
||||
|
||||
[identity function]: http://en.wikipedia.org/wiki/Identity_function
|
||||
@@ -0,0 +1,288 @@
|
||||
jQuery#typeahead
|
||||
----------------
|
||||
|
||||
The UI component of typeahead.js is available as a jQuery plugin. It's
|
||||
responsible for rendering suggestions and handling DOM interactions.
|
||||
|
||||
Table of Contents
|
||||
-----------------
|
||||
|
||||
* [Features](#features)
|
||||
* [Usage](#usage)
|
||||
* [API](#api)
|
||||
* [Options](#options)
|
||||
* [Datasets](#datasets)
|
||||
* [Custom Events](#custom-events)
|
||||
* [Class Names](#class-names)
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Displays suggestions to end-users as they type
|
||||
* Shows top suggestion as a hint (i.e. background text)
|
||||
* Supports custom templates to allow for UI flexibility
|
||||
* Works well with RTL languages and input method editors
|
||||
* Highlights query matches within the suggestion
|
||||
* Triggers custom events to encourage extensibility
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
### API
|
||||
|
||||
* [`jQuery#typeahead(options, [*datasets])`](#jquerytypeaheadoptions-datasets)
|
||||
* [`jQuery#typeahead('val')`](#jquerytypeaheadval)
|
||||
* [`jQuery#typeahead('val', val)`](#jquerytypeaheadval-val)
|
||||
* [`jQuery#typeahead('destroy')`](#jquerytypeaheaddestroy)
|
||||
* [`jQuery.fn.typeahead.noConflict()`](#jqueryfntypeaheadnoconflict)
|
||||
|
||||
#### jQuery#typeahead(options, [\*datasets])
|
||||
|
||||
For a given `input[type="text"]`, enables typeahead functionality. `options`
|
||||
is an options hash that's used for configuration. Refer to [Options](#options)
|
||||
for more info regarding the available configs. Subsequent arguments
|
||||
(`*datasets`), are individual option hashes for datasets. For more details
|
||||
regarding datasets, refer to [Datasets](#datasets).
|
||||
|
||||
```javascript
|
||||
$('.typeahead').typeahead({
|
||||
minLength: 3,
|
||||
highlight: true
|
||||
},
|
||||
{
|
||||
name: 'my-dataset',
|
||||
source: mySource
|
||||
});
|
||||
```
|
||||
|
||||
#### jQuery#typeahead('val')
|
||||
|
||||
Returns the current value of the typeahead. The value is the text the user has
|
||||
entered into the `input` element.
|
||||
|
||||
```javascript
|
||||
var myVal = $('.typeahead').typeahead('val');
|
||||
```
|
||||
|
||||
#### jQuery#typeahead('val', val)
|
||||
|
||||
Sets the value of the typeahead. This should be used in place of `jQuery#val`.
|
||||
|
||||
```javascript
|
||||
$('.typeahead').typeahead('val', myVal);
|
||||
```
|
||||
|
||||
#### jQuery#typeahead('open')
|
||||
|
||||
Opens the suggestion menu.
|
||||
|
||||
```javascript
|
||||
$('.typeahead').typeahead('open');
|
||||
```
|
||||
|
||||
#### jQuery#typeahead('close')
|
||||
|
||||
Closes the suggestion menu.
|
||||
|
||||
```javascript
|
||||
$('.typeahead').typeahead('close');
|
||||
```
|
||||
|
||||
#### jQuery#typeahead('destroy')
|
||||
|
||||
Removes typeahead functionality and reverts the `input` element back to its
|
||||
original state.
|
||||
|
||||
```javascript
|
||||
$('.typeahead').typeahead('destroy');
|
||||
```
|
||||
|
||||
#### jQuery.fn.typeahead.noConflict()
|
||||
|
||||
Returns a reference to the typeahead plugin and reverts `jQuery.fn.typeahead`
|
||||
to its previous value. Can be used to avoid naming collisions.
|
||||
|
||||
```javascript
|
||||
var typeahead = jQuery.fn.typeahead.noConflict();
|
||||
jQuery.fn._typeahead = typeahead;
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
When initializing a typeahead, there are a number of options you can configure.
|
||||
|
||||
* `highlight` – If `true`, when suggestions are rendered, pattern matches
|
||||
for the current query in text nodes will be wrapped in a `strong` element with
|
||||
its class set to `{{classNames.highlight}}`. Defaults to `false`.
|
||||
|
||||
* `hint` – If `false`, the typeahead will not show a hint. Defaults to `true`.
|
||||
|
||||
* `minLength` – The minimum character length needed before suggestions start
|
||||
getting rendered. Defaults to `1`.
|
||||
|
||||
* `classNames` – For overriding the default class names used. See
|
||||
[Class Names](#class-names) for more details.
|
||||
|
||||
### Datasets
|
||||
|
||||
A typeahead is composed of one or more datasets. When an end-user modifies the
|
||||
value of a typeahead, each dataset will attempt to render suggestions for the
|
||||
new value.
|
||||
|
||||
For most use cases, one dataset should suffice. It's only in the scenario where
|
||||
you want rendered suggestions to be grouped based on some sort of categorical
|
||||
relationship that you'd need to use multiple datasets. For example, on
|
||||
twitter.com, the search typeahead groups results into recent searches, trends,
|
||||
and accounts – that would be a great use case for using multiple datasets.
|
||||
|
||||
Datasets can be configured using the following options.
|
||||
|
||||
* `source` – The backing data source for suggestions. Expected to be a function
|
||||
with the signature `(query, syncResults, asyncResults)`. `syncResults` should
|
||||
be called with suggestions computed synchronously and `asyncResults` should be
|
||||
called with suggestions computed asynchronously (e.g. suggestions that come
|
||||
for an AJAX request). `source` can also be a Bloodhound instance.
|
||||
**Required**.
|
||||
|
||||
* `async` – Lets the dataset know if async suggestions should be expected. If
|
||||
not set, this information is inferred from the signature of `source` i.e.
|
||||
if the `source` function expects 3 arguments, `async` will be set to `true`.
|
||||
|
||||
* `name` – The name of the dataset. This will be appended to
|
||||
`{{classNames.dataset}}-` to form the class name of the containing DOM
|
||||
element. Must only consist of underscores, dashes, letters (`a-z`), and
|
||||
numbers. Defaults to a random number.
|
||||
|
||||
* `limit` – The max number of suggestions to be displayed. Defaults to `5`.
|
||||
|
||||
* `display` – For a given suggestion, determines the string representation
|
||||
of it. This will be used when setting the value of the input control after a
|
||||
suggestion is selected. Can be either a key string or a function that
|
||||
transforms a suggestion object into a string. Defaults to stringifying the
|
||||
suggestion.
|
||||
|
||||
* `templates` – A hash of templates to be used when rendering the dataset. Note
|
||||
a precompiled template is a function that takes a JavaScript object as its
|
||||
first argument and returns a HTML string.
|
||||
|
||||
* `notFound` – Rendered when `0` suggestions are available for the given
|
||||
query. Can be either a HTML string or a precompiled template. If it's a
|
||||
precompiled template, the passed in context will contain `query`.
|
||||
|
||||
* `pending` - Rendered when `0` synchronous suggestions are available but
|
||||
asynchronous suggestions are expected. Can be either a HTML string or a
|
||||
precompiled template. If it's a precompiled template, the passed in context
|
||||
will contain `query`.
|
||||
|
||||
* `header`– Rendered at the top of the dataset when suggestions are present.
|
||||
Can be either a HTML string or a precompiled template. If it's a precompiled
|
||||
template, the passed in context will contain `query` and `suggestions`.
|
||||
|
||||
* `footer`– Rendered at the bottom of the dataset when suggestions are
|
||||
present. Can be either a HTML string or a precompiled template. If it's a
|
||||
precompiled template, the passed in context will contain `query` and
|
||||
`suggestions`.
|
||||
|
||||
* `suggestion` – Used to render a single suggestion. If set, this has to be a
|
||||
precompiled template. The associated suggestion object will serve as the
|
||||
context. Defaults to the value of `display` wrapped in a `div` tag i.e.
|
||||
`<div>{{value}}</div>`.
|
||||
|
||||
### Custom Events
|
||||
|
||||
The following events get triggered on the input element during the life-cycle of
|
||||
a typeahead.
|
||||
|
||||
* `typeahead:active` – Fired when the typeahead moves to active state.
|
||||
|
||||
* `typeahead:idle` – Fired when the typeahead moves to idle state.
|
||||
|
||||
* `typeahead:open` – Fired when the results container is opened.
|
||||
|
||||
* `typeahead:close` – Fired when the results container is closed.
|
||||
|
||||
* `typeahead:change` – Normalized version of the native [`change` event].
|
||||
Fired when input loses focus and the value has changed since it originally
|
||||
received focus.
|
||||
|
||||
* `typeahead:render` – Fired when suggestions are rendered for a dataset. The
|
||||
event handler will be invoked with 4 arguments: the jQuery event object, the
|
||||
suggestions that were rendered, a flag indicating whether the suggestions
|
||||
were fetched asynchronously, and the name of the dataset the rendering
|
||||
occurred in.
|
||||
|
||||
* `typeahead:select` – Fired when a suggestion is selected. The event handler
|
||||
will be invoked with 2 arguments: the jQuery event object and the suggestion
|
||||
object that was selected.
|
||||
|
||||
* `typeahead:autocomplete` – Fired when a autocompletion occurs. The
|
||||
event handler will be invoked with 2 arguments: the jQuery event object and
|
||||
the suggestion object that was used for autocompletion.
|
||||
|
||||
* `typeahead:cursorchange` – Fired when the results container cursor moves. The
|
||||
event handler will be invoked with 2 arguments: the jQuery event object and
|
||||
the suggestion object that was moved to.
|
||||
|
||||
* `typeahead:asyncrequest` – Fired when an async request for suggestions is
|
||||
sent. The event handler will be invoked with 3 arguments: the jQuery event
|
||||
object, the current query, and the name of the dataset the async request
|
||||
belongs to.
|
||||
|
||||
* `typeahead:asynccancel` – Fired when an async request is cancelled. The event
|
||||
handler will be invoked with 3 arguments: the jQuery event object, the current
|
||||
query, and the name of the dataset the async request belonged to.
|
||||
|
||||
* `typeahead:asyncreceive` – Fired when an async request completes. The event
|
||||
handler will be invoked with 3 arguments: the jQuery event object, the current
|
||||
query, and the name of the dataset the async request belongs to.
|
||||
|
||||
Example usage:
|
||||
|
||||
```
|
||||
$('.typeahead').bind('typeahead:select', function(ev, suggestion) {
|
||||
console.log('Selection: ' + suggestion);
|
||||
});
|
||||
```
|
||||
|
||||
**NOTE**: Every event does not supply the same arguments. See the event
|
||||
descriptions above for details on each event's argument list.
|
||||
|
||||
<!-- section links -->
|
||||
|
||||
[`change` event]: https://developer.mozilla.org/en-US/docs/Web/Events/change
|
||||
|
||||
### Class Names
|
||||
|
||||
* `input` - Added to input that's initialized into a typeahead. Defaults to
|
||||
`tt-input`.
|
||||
|
||||
* `hint` - Added to hint input. Defaults to `tt-hint`.
|
||||
|
||||
* `menu` - Added to menu element. Defaults to `tt-menu`.
|
||||
|
||||
* `dataset` - Added to dataset elements. to Defaults to `tt-dataset`.
|
||||
|
||||
* `suggestion` - Added to suggestion elements. Defaults to `tt-suggestion`.
|
||||
|
||||
* `empty` - Added to menu element when it contains no content. Defaults to
|
||||
`tt-empty`.
|
||||
|
||||
* `open` - Added to menu element when it is opened. Defaults to `tt-open`.
|
||||
|
||||
* `cursor` - Added to suggestion element when menu cursor moves to said
|
||||
suggestion. Defaults to `tt-cursor`.
|
||||
|
||||
* `highlight` - Added to the element that wraps highlighted text. Defaults to
|
||||
`tt-highlight`.
|
||||
|
||||
To override any of these defaults, you can use the `classNames` option:
|
||||
|
||||
```javascript
|
||||
$('.typeahead').typeahead({
|
||||
classNames: {
|
||||
input: 'Typeahead-input',
|
||||
hint: 'Typeahead-hint',
|
||||
selectable: 'Typeahead-selectable'
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,234 @@
|
||||
Migrating to typeahead.js v0.10.0
|
||||
=================================
|
||||
|
||||
Preamble
|
||||
--------
|
||||
|
||||
v0.10.0 of typeahead.js ended up being almost a complete rewrite. Many things
|
||||
stayed the same, but there were a handful of changes you need to be aware of
|
||||
if you plan on upgrading from an older version. This document aims to call out
|
||||
those changes and explain what you need to do in order to have an painless
|
||||
upgrade.
|
||||
|
||||
Notable Changes
|
||||
----------------
|
||||
|
||||
### First Argument to the jQuery Plugin
|
||||
|
||||
In v0.10.0, the first argument to `jQuery#typeahead` is an options hash that
|
||||
can be used to configure the behavior of the typeahead. This is in contrast
|
||||
to previous versions where `jQuery#typeahead` expected just a series of datasets
|
||||
to be passed to it:
|
||||
|
||||
```javascript
|
||||
// pre-v0.10.0
|
||||
$('.typeahead').typeahead(myDataset);
|
||||
|
||||
// v0.10.0
|
||||
$('.typeahead').typeahead({
|
||||
highlight: true,
|
||||
hint: false
|
||||
}, myDataset);
|
||||
```
|
||||
|
||||
If you're fine with the default configuration, you can just pass `null` as the
|
||||
first argument:
|
||||
|
||||
```javascript
|
||||
$('.typeahead').typeahead(null, myDataset);
|
||||
```
|
||||
|
||||
### Bloodhound Suggestion Engine
|
||||
|
||||
The most notable change in v0.10.0 is that typeahead.js has been decomposed into
|
||||
a suggestion engine and a UI view. As part of this change, the way you configure
|
||||
datasets has changed. Previously, a dataset config would have looked like:
|
||||
|
||||
```javascript
|
||||
{
|
||||
valueKey: 'num',
|
||||
local: [{ num: 'one' }, { num: 'two' }, { num: 'three' }],
|
||||
prefetch: '/prefetch',
|
||||
remote: '/remote?q=%QUERY'
|
||||
}
|
||||
```
|
||||
|
||||
In v0.10.0, an equivalent dataset config would look like:
|
||||
|
||||
```javascript
|
||||
{
|
||||
displayKey: 'num',
|
||||
source: mySource
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, `local`, `prefetch`, and `remote` are no longer defined at the
|
||||
dataset level. Instead, all you set in a dataset config is `source`. `source` is
|
||||
expected to be a function with the signature `function(query, callback)`. When a
|
||||
typeahead's query changes, suggestions will be requested from `source`. It's
|
||||
expected `source` will compute the suggestion set and invoke `callback` with an array
|
||||
of suggestion objects. The typeahead will then go on to render those suggestions.
|
||||
|
||||
If you're wondering if you can still configure `local`, `prefetch`, and
|
||||
`remote`, don't worry, that's where the Bloodhound suggestion engine comes in.
|
||||
Here's how you would define `mySource` which was referenced in the previous
|
||||
code snippet:
|
||||
|
||||
```
|
||||
var mySource = new Bloodhound({
|
||||
datumTokenizer: function(d) {
|
||||
return Bloodhound.tokenizers.whitespace(d.num);
|
||||
},
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
local: [{ num: 'one' }, { num: 'two' }, { num: 'three' }],
|
||||
prefetch: '/prefetch',
|
||||
remote: '/remote?q=%QUERY'
|
||||
});
|
||||
|
||||
// this kicks off the loading and processing of local and prefetch data
|
||||
// the suggestion engine will be useless until it is initialized
|
||||
mySource.initialize();
|
||||
```
|
||||
|
||||
In the above snippet, a Bloodhound suggestion engine is initialized and that's
|
||||
what will be used as the source of your dataset. There's still one last thing
|
||||
that needs to be done before you can use a Bloodhound suggestion engine as the
|
||||
source of a dataset. Because datasets expect `source` to be function, the
|
||||
Bloodhound instance needs to be wrapped in an adapter so it can meet that
|
||||
expectation.
|
||||
|
||||
```
|
||||
mySource = mySource.ttAdapter();
|
||||
```
|
||||
|
||||
Put it all together:
|
||||
|
||||
```javascript
|
||||
var mySource = new Bloodhound({
|
||||
datumTokenizer: function(d) {
|
||||
return Bloodhound.tokenizers.whitespace(d.num);
|
||||
},
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
local: [{ num: 'one' }, { num: 'two' }, { num: 'three' }],
|
||||
prefetch: '/prefetch',
|
||||
remote: '/remote?q=%QUERY'
|
||||
});
|
||||
|
||||
mySource.initialize();
|
||||
|
||||
$('.typeahead').typeahead(null, {
|
||||
displayKey: 'num',
|
||||
source: mySource.ttAdapter()
|
||||
});
|
||||
```
|
||||
|
||||
### Tokenization Methods Must Be Provided
|
||||
|
||||
The Bloodhound suggestion engine is token-based, so how datums and queries are
|
||||
tokenized plays a vital role in the quality of search results. Pre-v0.10.0,
|
||||
it was not possible to configure the tokenization method. Starting in v0.10.0,
|
||||
you **must** specify how you want datums and queries tokenized.
|
||||
|
||||
The most common tokenization methods split a given string on whitespace or
|
||||
non-word characters. Bloodhound provides implementations for those methods
|
||||
out of the box:
|
||||
|
||||
```javascript
|
||||
// returns ['one', 'two', 'twenty-five']
|
||||
Bloodhound.tokenizers.whitespace(' one two twenty-five');
|
||||
|
||||
// returns ['one', 'two', 'twenty', 'five']
|
||||
Bloodhound.tokenizers.nonword(' one two twenty-five');
|
||||
```
|
||||
|
||||
For query tokenization, you'll probably want to use one of the above methods.
|
||||
For datum tokenization, this is where you may want to do something a tad bit
|
||||
more advanced.
|
||||
|
||||
For datums, sometimes you want tokens to be dervied from more than one property.
|
||||
For example, if you were building a search engine for GitHub repositories, it'd
|
||||
probably be wise to have tokens derived from the repo's name, owner, and
|
||||
primary language:
|
||||
|
||||
```javascript
|
||||
var repos = [
|
||||
{ name: 'example', owner: 'John Doe', language: 'JavaScript' },
|
||||
{ name: 'another example', owner: 'Joe Doe', language: 'Scala' }
|
||||
];
|
||||
|
||||
function customTokenizer(datum) {
|
||||
var nameTokens = Bloodhound.tokenizers.whitespace(datum.name);
|
||||
var ownerTokens = Bloodhound.tokenizers.whitespace(datum.owner);
|
||||
var languageTokens = Bloodhound.tokenizers.whitespace(datum.language);
|
||||
|
||||
return nameTokens.concat(ownerTokens).concat(languageTokens);
|
||||
}
|
||||
```
|
||||
|
||||
There may also be the scenario where you want datum tokenization to be performed
|
||||
on the backend. The best way to do that is to just add a property to your datums
|
||||
that contains those tokens. You can then provide a tokenizer that just returns
|
||||
the already existing tokens:
|
||||
|
||||
```javascript
|
||||
var sports = [
|
||||
{ value: 'football', tokens: ['football', 'pigskin'] },
|
||||
{ value: 'basketball', tokens: ['basketball', 'bball'] }
|
||||
];
|
||||
|
||||
function customTokenizer(datum) { return datum.tokens; }
|
||||
```
|
||||
|
||||
There are plenty of other ways you could go about tokenizing datums, it really
|
||||
just depends on what you are trying to accomplish.
|
||||
|
||||
### String Datums Are No Longer Supported
|
||||
|
||||
Dropping support for string datums was a difficult choice, but in the end it
|
||||
made sense for a number of reasons. If you still want to hydrate the suggestion
|
||||
engine with string datums, you'll need to use the `filter` function:
|
||||
|
||||
```javascript
|
||||
var engine = new Bloodhound({
|
||||
prefetch: {
|
||||
url: '/data',
|
||||
filter: function(data) {
|
||||
// assume data is an array of strings e.g. ['one', 'two', 'three']
|
||||
return $.map(data, function(str) { return { value: str }; });
|
||||
},
|
||||
datumTokenizer: function(d) {
|
||||
return Bloodhound.tokenizers.whitespace(d.value);
|
||||
},
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Precompiled Templates Are Now Required
|
||||
|
||||
In previous versions of typeahead.js, you could specify a string template along
|
||||
with the templating engine that should be used to compile/render it. In
|
||||
v0.10.0, you can no longer specify templating engines; instead you must provide
|
||||
precompiled templates. Precompiled templates are functions that take one
|
||||
argument: the context the template should be rendered with.
|
||||
|
||||
Most of the popular templating engines allow for the creation of precompiled
|
||||
templates. For example, you can generate one using Handlebars by doing the
|
||||
following:
|
||||
|
||||
```javascript
|
||||
var precompiledTemplate = Handlebars.compile('<p>{{value}}</p>');
|
||||
```
|
||||
|
||||
[Handlebars]: http://handlebarsjs.com/
|
||||
|
||||
### CSS Class Changes
|
||||
|
||||
`tt-is-under-cursor` is now `tt-cursor` - Applied to a hovered-on suggestion (either via cursor or arrow key).
|
||||
|
||||
`tt-query` is now `tt-input` - Applied to the typeahead input field.
|
||||
|
||||
Something Missing?
|
||||
------------------
|
||||
|
||||
If something is missing from this migration guide, pull requests are accepted :)
|
||||
Reference in New Issue
Block a user