mirror of
https://github.com/zhigang1992/typeahead.js.git
synced 2026-04-29 01:34:55 +08:00
Merge pull request #115 from jharding/61-configurable-value-key
Make value key configurable
This commit is contained in:
@@ -21,7 +21,8 @@ var Dataset = (function() {
|
||||
this.limit = o.limit || 5;
|
||||
this.header = o.header;
|
||||
this.footer = o.footer;
|
||||
this.template = compileTemplate(o.template, o.engine);
|
||||
this.valueKey = o.valueKey || 'value';
|
||||
this.template = compileTemplate(o.template, o.engine, this.valueKey);
|
||||
|
||||
// used in #initialize
|
||||
this.local = o.local;
|
||||
@@ -95,18 +96,25 @@ var Dataset = (function() {
|
||||
},
|
||||
|
||||
_processData: function(data) {
|
||||
var itemHash = {}, adjacencyList = {};
|
||||
var that = this, itemHash = {}, adjacencyList = {};
|
||||
|
||||
utils.each(data, function(i, item) {
|
||||
var id;
|
||||
utils.each(data, function(i, datum) {
|
||||
var value = utils.isString(datum) ? datum : datum[that.valueKey],
|
||||
tokens = datum.tokens || utils.tokenizeText(value),
|
||||
item = { value: value, tokens: tokens },
|
||||
id;
|
||||
|
||||
// convert string datums to datum objects
|
||||
if (utils.isString(item)) {
|
||||
item = { value: item, tokens: utils.tokenizeText(item) };
|
||||
if (utils.isString(datum)) {
|
||||
item.datum = {};
|
||||
item.datum[that.valueKey] = datum;
|
||||
}
|
||||
|
||||
else {
|
||||
item.datum = datum;
|
||||
}
|
||||
|
||||
// filter out falsy tokens
|
||||
item.tokens = utils.filter(item.tokens || [], function(token) {
|
||||
item.tokens = utils.filter(item.tokens, function(token) {
|
||||
return !utils.isBlankString(token);
|
||||
});
|
||||
|
||||
@@ -197,41 +205,6 @@ var Dataset = (function() {
|
||||
return suggestions;
|
||||
},
|
||||
|
||||
_compareItems: function(a, b, areLocalItems) {
|
||||
var aScoreBoost = !a.score_boost ? 0 : a.score_boost,
|
||||
bScoreBoost = !b.score_boost ? 0 : b.score_boost,
|
||||
aScore = !a.score ? 0 : a.score,
|
||||
bScore = !b.score ? 0 : b.score;
|
||||
|
||||
if(areLocalItems) {
|
||||
return (b.weight + bScoreBoost) - (a.weight + aScoreBoost);
|
||||
} else {
|
||||
return (bScore + bScoreBoost) - (aScore + aScoreBoost);
|
||||
}
|
||||
},
|
||||
|
||||
_ranker: function(a, b) {
|
||||
if (this._customRanker) {
|
||||
return this._customRanker(a, b);
|
||||
} else {
|
||||
// Anything local should always be first (anything with a non-zero weight) and remote results (non-zero scores), and sort by weight/score within each category
|
||||
var aIsLocal = a.weight && a.weight !== 0;
|
||||
var bIsLocal = b.weight && b.weight !== 0;
|
||||
if (aIsLocal && !bIsLocal) {
|
||||
return -1;
|
||||
} else if (bIsLocal && !aIsLocal) {
|
||||
return 1;
|
||||
} else {
|
||||
return (aIsLocal && bIsLocal) ? this._compareItems(a, b, true) : this._compareItems(a, b, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_processRemoteSuggestions: function(callback, matchedItems) {
|
||||
var that = this;
|
||||
|
||||
},
|
||||
|
||||
// public methods
|
||||
// ---------------
|
||||
|
||||
@@ -256,9 +229,7 @@ var Dataset = (function() {
|
||||
getSuggestions: function(query, cb) {
|
||||
var that = this,
|
||||
terms = utils.tokenizeQuery(query),
|
||||
suggestions = this._getLocalSuggestions(terms)
|
||||
.sort(this._ranker)
|
||||
.slice(0, this.limit);
|
||||
suggestions = this._getLocalSuggestions(terms).slice(0, this.limit);
|
||||
|
||||
cb && cb(suggestions);
|
||||
|
||||
@@ -301,7 +272,7 @@ var Dataset = (function() {
|
||||
|
||||
return Dataset;
|
||||
|
||||
function compileTemplate(template, engine) {
|
||||
function compileTemplate(template, engine, valueKey) {
|
||||
var wrapper = '<div class="tt-suggestion">%body</div>',
|
||||
compiledTemplate;
|
||||
|
||||
@@ -314,7 +285,7 @@ var Dataset = (function() {
|
||||
else {
|
||||
compiledTemplate = {
|
||||
render: function(context) {
|
||||
return wrapper.replace('%body', '<p>' + context.value + '</p>');
|
||||
return wrapper.replace('%body', '<p>' + context[valueKey] + '</p>');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ var DropdownView = (function() {
|
||||
|
||||
_handleSelection: function($e) {
|
||||
var $suggestion = $($e.currentTarget);
|
||||
this.trigger('suggestionSelected', getSuggestionData($suggestion));
|
||||
this.trigger('suggestionSelected', extractSuggestion($suggestion));
|
||||
},
|
||||
|
||||
_show: function() {
|
||||
@@ -94,7 +94,7 @@ var DropdownView = (function() {
|
||||
}
|
||||
|
||||
$underCursor = $suggestions.eq(nextIndex).addClass('tt-is-under-cursor');
|
||||
this.trigger('cursorMoved', getSuggestionData($underCursor));
|
||||
this.trigger('cursorMoved', extractSuggestion($underCursor));
|
||||
},
|
||||
|
||||
_getSuggestions: function() {
|
||||
@@ -166,16 +166,16 @@ var DropdownView = (function() {
|
||||
.filter('.tt-is-under-cursor')
|
||||
.first();
|
||||
|
||||
return $suggestion.length > 0 ? getSuggestionData($suggestion) : null;
|
||||
return $suggestion.length > 0 ? extractSuggestion($suggestion) : null;
|
||||
},
|
||||
|
||||
getFirstSuggestion: function() {
|
||||
var $suggestion = this._getSuggestions().first();
|
||||
|
||||
return $suggestion.length > 0 ? getSuggestionData($suggestion) : null;
|
||||
return $suggestion.length > 0 ? extractSuggestion($suggestion) : null;
|
||||
},
|
||||
|
||||
renderSuggestions: function(query, dataset, suggestions) {
|
||||
renderSuggestions: function(dataset, suggestions) {
|
||||
var datasetClassName = 'tt-dataset-' + dataset.name,
|
||||
$suggestionsList,
|
||||
$dataset = this.$menu.find('.' + datasetClassName),
|
||||
@@ -204,7 +204,7 @@ var DropdownView = (function() {
|
||||
fragment = document.createDocumentFragment();
|
||||
|
||||
utils.each(suggestions, function(i, suggestion) {
|
||||
elBuilder.innerHTML = dataset.template.render(suggestion);
|
||||
elBuilder.innerHTML = dataset.template.render(suggestion.datum);
|
||||
|
||||
$el = $(elBuilder.firstChild)
|
||||
.css(css.suggestion)
|
||||
@@ -251,7 +251,7 @@ var DropdownView = (function() {
|
||||
// helper functions
|
||||
// ----------------
|
||||
|
||||
function getSuggestionData($el) {
|
||||
function extractSuggestion($el) {
|
||||
return $el.data('suggestion');
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -217,32 +217,25 @@ var TypeaheadView = (function() {
|
||||
byClick && utils.isMsie() ?
|
||||
utils.defer(this.dropdownView.close) : this.dropdownView.close();
|
||||
|
||||
this.eventBus.trigger('selected', suggestion);
|
||||
this.eventBus.trigger('selected', suggestion.datum);
|
||||
}
|
||||
},
|
||||
|
||||
_getSuggestions: function() {
|
||||
var that = this,
|
||||
query = this.inputView.getQuery();
|
||||
var that = this, query = this.inputView.getQuery();
|
||||
|
||||
if (utils.isBlankString(query)) {
|
||||
return;
|
||||
}
|
||||
if (utils.isBlankString(query)) { return; }
|
||||
|
||||
utils.each(this.datasets, function(i, dataset) {
|
||||
dataset.getSuggestions(query, function(suggestions) {
|
||||
that._renderSuggestions(query, dataset, suggestions);
|
||||
// only render the suggestions if the query hasn't changed
|
||||
if (query === that.inputView.getQuery()) {
|
||||
that.dropdownView.renderSuggestions(dataset, suggestions);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_renderSuggestions: function(query, dataset, suggestions) {
|
||||
if (query !== this.inputView.getQuery()) { return; }
|
||||
|
||||
suggestions = suggestions.slice(0, dataset.limit);
|
||||
this.dropdownView.renderSuggestions(query, dataset, suggestions);
|
||||
},
|
||||
|
||||
_autocomplete: function(e) {
|
||||
var isCursorAtEnd, ignoreEvent, query, hint, suggestion;
|
||||
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
describe('Dataset', function() {
|
||||
var fixtureData = ['grape', 'coconut', 'cake', 'tea', 'coffee'],
|
||||
var fixtureStrings = ['grape', 'coconut', 'cake', 'tea', 'coffee'],
|
||||
fixtureDatums = [
|
||||
{ value: 'grape' },
|
||||
{ value: 'coconut' },
|
||||
{ value: 'cake' },
|
||||
{ value: 'tea' },
|
||||
{ value: 'coffee' }
|
||||
],
|
||||
expectedAdjacencyList = {
|
||||
g: ['grape'],
|
||||
c: ['coconut', 'cake', 'coffee'],
|
||||
t: ['tea']
|
||||
},
|
||||
expectedItemHash = {
|
||||
grape: { tokens: ['grape'], value: 'grape' },
|
||||
coconut: { tokens: ['coconut'], value: 'coconut' },
|
||||
cake: { tokens: ['cake'], value: 'cake' },
|
||||
tea: { tokens: ['tea'], value: 'tea' },
|
||||
coffee: { tokens: ['coffee'], value: 'coffee' }
|
||||
grape: createItem('grape'),
|
||||
coconut: createItem('coconut'),
|
||||
cake: createItem('cake'),
|
||||
tea: createItem('tea'),
|
||||
coffee: createItem('coffee')
|
||||
},
|
||||
prefetchResp = {
|
||||
status: 200,
|
||||
responseText: JSON.stringify(fixtureData)
|
||||
responseText: JSON.stringify(fixtureStrings)
|
||||
},
|
||||
mockStorageFns = {
|
||||
getMiss: function() {
|
||||
@@ -56,7 +63,7 @@ describe('Dataset', function() {
|
||||
|
||||
describe('#constructor', function() {
|
||||
it('should initialize persistent storage', function() {
|
||||
expect(new Dataset({ local: fixtureData }).storage).toBeDefined();
|
||||
expect(new Dataset({ local: fixtureStrings }).storage).toBeDefined();
|
||||
expect(PersistentStorage).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -82,7 +89,7 @@ describe('Dataset', function() {
|
||||
|
||||
describe('when called with no template', function() {
|
||||
beforeEach(function() {
|
||||
this.dataset = new Dataset({ local: fixtureData });
|
||||
this.dataset = new Dataset({ local: fixtureStrings });
|
||||
});
|
||||
|
||||
it('should compile default template', function() {
|
||||
@@ -94,7 +101,7 @@ describe('Dataset', function() {
|
||||
describe('when called with a template and engine', function() {
|
||||
beforeEach(function() {
|
||||
this.dataset = new Dataset({
|
||||
local: fixtureData,
|
||||
local: fixtureStrings,
|
||||
template: 't',
|
||||
engine: { compile: this.spy = jasmine.createSpy().andReturn('boo') }
|
||||
});
|
||||
@@ -113,7 +120,7 @@ describe('Dataset', function() {
|
||||
it('should return Deferred instance', function() {
|
||||
var returnVal;
|
||||
|
||||
this.dataset = new Dataset({ local: fixtureData });
|
||||
this.dataset = new Dataset({ local: fixtureStrings });
|
||||
returnVal = this.dataset.initialize();
|
||||
|
||||
// eh, have to rely on duck typing unfortunately
|
||||
@@ -124,13 +131,18 @@ describe('Dataset', function() {
|
||||
|
||||
describe('when called with local', function() {
|
||||
beforeEach(function() {
|
||||
this.dataset = new Dataset({ local: fixtureData });
|
||||
this.dataset.initialize();
|
||||
this.dataset1 = new Dataset({ local: fixtureStrings });
|
||||
this.dataset2 = new Dataset({ local: fixtureDatums });
|
||||
|
||||
this.dataset1.initialize();
|
||||
this.dataset2.initialize();
|
||||
});
|
||||
|
||||
it('should process and merge the data', function() {
|
||||
expect(this.dataset.itemHash).toEqual(expectedItemHash);
|
||||
expect(this.dataset.adjacencyList).toEqual(expectedAdjacencyList);
|
||||
expect(this.dataset1.itemHash).toEqual(expectedItemHash);
|
||||
expect(this.dataset1.adjacencyList).toEqual(expectedAdjacencyList);
|
||||
expect(this.dataset2.itemHash).toEqual(expectedItemHash);
|
||||
expect(this.dataset2.adjacencyList).toEqual(expectedAdjacencyList);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -158,9 +170,7 @@ describe('Dataset', function() {
|
||||
|
||||
describe('if filter was passed in', function() {
|
||||
var filteredAdjacencyList = { f: ['filter'] },
|
||||
filteredItemHash = {
|
||||
filter: { tokens: ['filter'], value: 'filter' }
|
||||
};
|
||||
filteredItemHash = { filter: createItem('filter') };
|
||||
|
||||
beforeEach(function() {
|
||||
this.dataset = new Dataset({
|
||||
@@ -181,7 +191,7 @@ describe('Dataset', function() {
|
||||
expect(this.request).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should process and merge filtered data', function() {
|
||||
it('should process and merge fileered data', function() {
|
||||
expect(this.dataset.adjacencyList).toEqual(filteredAdjacencyList);
|
||||
expect(this.dataset.itemHash).toEqual(filteredItemHash);
|
||||
});
|
||||
@@ -251,31 +261,9 @@ describe('Dataset', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Datasource options', function() {
|
||||
describe('Matching, combining, returning results', function() {
|
||||
beforeEach(function() {
|
||||
this.dataset = new Dataset({ local: fixtureData });
|
||||
this.dataset.initialize();
|
||||
});
|
||||
|
||||
it('allow for a custom ranking function to be defined', function() {
|
||||
this.dataset._customRanker = function(a, b) {
|
||||
return a.value.length > b.value.length ?
|
||||
1 : a.value.length === b.value.length ? 0 : -1;
|
||||
};
|
||||
|
||||
this.dataset.getSuggestions('c', function(items) {
|
||||
expect(items).toEqual([
|
||||
{ tokens: ['cake'], value: 'cake' },
|
||||
{ tokens: ['coffee'], value: 'coffee' },
|
||||
{ tokens: ['coconut'], value: 'coconut' }
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Matching, ranking, combining, returning results', function() {
|
||||
beforeEach(function() {
|
||||
this.dataset = new Dataset({ local: fixtureData, remote: '/remote' });
|
||||
this.dataset = new Dataset({ local: fixtureStrings, remote: '/remote' });
|
||||
this.dataset.initialize();
|
||||
});
|
||||
|
||||
@@ -283,9 +271,9 @@ describe('Dataset', function() {
|
||||
this.dataset.limit = 3;
|
||||
this.dataset.getSuggestions('c', function(items) {
|
||||
expect(items).toEqual([
|
||||
{ tokens: ['coconut'], value: 'coconut' },
|
||||
{ tokens: ['cake'], value: 'cake' },
|
||||
{ tokens: ['coffee'], value: 'coffee' }
|
||||
createItem('coconut'),
|
||||
createItem('cake'),
|
||||
createItem('coffee')
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -294,9 +282,9 @@ describe('Dataset', function() {
|
||||
this.dataset.limit = 100;
|
||||
this.dataset.getSuggestions('c', function(items) {
|
||||
expect(items).toEqual([
|
||||
{ tokens: ['coconut'], value: 'coconut' },
|
||||
{ tokens: ['cake'], value: 'cake' },
|
||||
{ tokens: ['coffee'], value: 'coffee' }
|
||||
createItem('coconut'),
|
||||
createItem('cake'),
|
||||
createItem('coffee')
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -306,9 +294,9 @@ describe('Dataset', function() {
|
||||
it('matches', function() {
|
||||
this.dataset.getSuggestions('c', function(items) {
|
||||
expect(items).toEqual([
|
||||
{ tokens: ['coconut'], value: 'coconut' },
|
||||
{ tokens: ['cake'], value: 'cake' },
|
||||
{ tokens: ['coffee'], value: 'coffee' }
|
||||
createItem('coconut'),
|
||||
createItem('cake'),
|
||||
createItem('coffee')
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -350,22 +338,6 @@ describe('Dataset', function() {
|
||||
expectedItemHash.grape
|
||||
]);
|
||||
});
|
||||
|
||||
it('sorts results: local first, then remote, sorted by graph weight / score within each local/remote section', function() {
|
||||
expect([
|
||||
{ id: 1, weight: 1000, score: 0 },
|
||||
{ id: 2, weight: 500, score: 0 },
|
||||
{ id: 3, weight: 1500, score: 0 },
|
||||
{ id: 4, weight: 0, score: 100000 },
|
||||
{ id: 5, weight: 0, score: 250000 }
|
||||
].sort(this.dataset._ranker)).toEqual([
|
||||
{ id: 3, weight: 1500, score: 0 },
|
||||
{ id: 1, weight: 1000, score: 0 },
|
||||
{ id: 2, weight: 500, score: 0 },
|
||||
{ id: 5, weight: 0, score: 250000 },
|
||||
{ id: 4, weight: 0, score: 100000 }
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tokenization', function() {
|
||||
@@ -379,27 +351,22 @@ describe('Dataset', function() {
|
||||
|
||||
it('normalizes capitalization to match items', function() {
|
||||
this.dataset.getSuggestions('Cours', function(items) {
|
||||
expect(items)
|
||||
.toEqual([{ tokens: ['course', '106'], value: 'course-106' }]);
|
||||
expect(items).toEqual([createItem('course-106')]);
|
||||
});
|
||||
this.dataset.getSuggestions('cOuRsE 106', function(items) {
|
||||
expect(items)
|
||||
.toEqual([{ tokens: ['course', '106'], value: 'course-106' }]);
|
||||
expect(items).toEqual([createItem('course-106')]);
|
||||
});
|
||||
this.dataset.getSuggestions('one two', function(items) {
|
||||
expect(items)
|
||||
.toEqual([{ tokens: ['one', 'two'], value: 'One-Two' }]);
|
||||
expect(items).toEqual([createItem('One-Two')]);
|
||||
});
|
||||
this.dataset.getSuggestions('THREE TWO', function(items) {
|
||||
expect(items)
|
||||
.toEqual([{ tokens: ['two', 'three'], value: 'two three' }]);
|
||||
expect(items).toEqual([createItem('two three')]);
|
||||
});
|
||||
});
|
||||
|
||||
it('matches items with dashes', function() {
|
||||
this.dataset.getSuggestions('106 course', function(items) {
|
||||
expect(items)
|
||||
.toEqual([{ tokens: ['course', '106'], value: 'course-106' }]);
|
||||
expect(items).toEqual([createItem('course-106')]);
|
||||
});
|
||||
this.dataset.getSuggestions('course-106', function(items) {
|
||||
expect(items).toEqual([]);
|
||||
@@ -408,15 +375,14 @@ describe('Dataset', function() {
|
||||
|
||||
it('matches items with underscores', function() {
|
||||
this.dataset.getSuggestions('user name', function(items) {
|
||||
expect(items)
|
||||
.toEqual([{ tokens: ['user', 'name'], value: 'user_name' }]);
|
||||
expect(items).toEqual([createItem('user_name')]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with datum objects', function() {
|
||||
var fixtureData = [{ value: 'course-106', tokens: ['course-106'] }];
|
||||
var fixtureData = [{ value: 'course-106' }];
|
||||
|
||||
beforeEach(function() {
|
||||
this.dataset = new Dataset({ local: fixtureData });
|
||||
@@ -425,13 +391,24 @@ describe('Dataset', function() {
|
||||
|
||||
it('matches items with dashes', function() {
|
||||
this.dataset.getSuggestions('106 course', function(items) {
|
||||
expect(items).toEqual([]);
|
||||
expect(items).toEqual([createItem('course-106')]);
|
||||
});
|
||||
|
||||
this.dataset.getSuggestions('course-106', function(items) {
|
||||
expect(items)
|
||||
.toEqual([{ value: 'course-106', tokens: ['course-106'] }]);
|
||||
expect(items).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// helper functions
|
||||
// ----------------
|
||||
|
||||
function createItem(val) {
|
||||
return {
|
||||
value: val,
|
||||
tokens: utils.tokenizeText(val),
|
||||
datum: { value: val }
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ describe('DropdownView', function() {
|
||||
it('should trigger suggestionSelected', function() {
|
||||
expect(this.spy).toHaveBeenCalledWith({
|
||||
type: 'suggestionSelected',
|
||||
data: { value: 'one' }
|
||||
data: { value: 'one', tokens: ['one'], datum: { value: 'one' } }
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -431,7 +431,11 @@ describe('DropdownView', function() {
|
||||
|
||||
suggestion = this.dropdownView.getSuggestionUnderCursor();
|
||||
|
||||
expect(suggestion).toEqual({ value: 'one' });
|
||||
expect(suggestion).toEqual({
|
||||
value: 'one',
|
||||
tokens: ['one'],
|
||||
datum: { value: 'one' }
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -444,7 +448,11 @@ describe('DropdownView', function() {
|
||||
it('should return obj with data about suggestion under the cursor',
|
||||
function() {
|
||||
var suggestion = this.dropdownView.getFirstSuggestion();
|
||||
expect(suggestion).toEqual({ value: 'one' });
|
||||
expect(suggestion).toEqual({
|
||||
value: 'one',
|
||||
tokens: ['one'],
|
||||
datum: { value: 'one' }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -471,7 +479,7 @@ describe('DropdownView', function() {
|
||||
|
||||
describe('if new dataset', function() {
|
||||
beforeEach(function() {
|
||||
this.dropdownView.renderSuggestions('query', mockNewDataset, []);
|
||||
this.dropdownView.renderSuggestions(mockNewDataset, []);
|
||||
});
|
||||
|
||||
it('should render the header', function() {
|
||||
@@ -498,7 +506,7 @@ describe('DropdownView', function() {
|
||||
|
||||
spyOn(this.dropdownView, 'clearSuggestions');
|
||||
|
||||
this.dropdownView.renderSuggestions('query', mockOldDataset, []);
|
||||
this.dropdownView.renderSuggestions(mockOldDataset, []);
|
||||
});
|
||||
|
||||
it('should call clearSuggestions', function() {
|
||||
@@ -518,20 +526,19 @@ describe('DropdownView', function() {
|
||||
spyOn(this.dropdownView, 'clearSuggestions').andCallThrough();
|
||||
|
||||
this.dropdownView.renderSuggestions(
|
||||
'query',
|
||||
mockOldDataset,
|
||||
[{ value: 'i am a value' }]
|
||||
[{ datum: { value: 'i am a value' } }]
|
||||
);
|
||||
});
|
||||
|
||||
it('should overwrite previous suggestions', function() {
|
||||
var $suggestions = this.$testDataset.children(),
|
||||
$suggestion = $suggestions.first(),
|
||||
suggestion = $suggestion.data('suggestion');
|
||||
datum = $suggestion.data('suggestion').datum;
|
||||
|
||||
expect($suggestions.length).toBe(1);
|
||||
expect($suggestion).toHaveText('i am a value');
|
||||
expect(suggestion).toEqual({ value: 'i am a value' });
|
||||
expect(datum).toEqual({ value: 'i am a value' });
|
||||
});
|
||||
|
||||
it('should trigger suggestionsRendered', function() {
|
||||
@@ -563,8 +570,7 @@ describe('DropdownView', function() {
|
||||
// ----------------
|
||||
|
||||
function renderTestDataset(view, open) {
|
||||
var mockQuery = 'test q',
|
||||
mockDataset = {
|
||||
var mockDataset = {
|
||||
name: 'test' ,
|
||||
template: {
|
||||
render: function(c) {
|
||||
@@ -573,12 +579,12 @@ describe('DropdownView', function() {
|
||||
}
|
||||
},
|
||||
mockSuggestions = [
|
||||
{ value: 'one' },
|
||||
{ value: 'two' },
|
||||
{ value: 'three' }
|
||||
{ value: 'one', tokens: ['one'], datum: { value: 'one' } },
|
||||
{ value: 'two', tokens: ['two'], datum: { value: 'two' } },
|
||||
{ value: 'three', tokens: ['three'], datum: { value: 'three' } }
|
||||
];
|
||||
|
||||
view.renderSuggestions(mockQuery, mockDataset, mockSuggestions);
|
||||
view.renderSuggestions(mockDataset, mockSuggestions);
|
||||
open && view.open();
|
||||
|
||||
return $('#jasmine-fixtures .tt-dataset-test > .tt-suggestions');
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
|
||||
<script>
|
||||
$('.states').typeahead({
|
||||
valueKey: 'state',
|
||||
local: [
|
||||
"Alabama",
|
||||
"Alaska",
|
||||
|
||||
Reference in New Issue
Block a user