Skip to content

Commit a362ce1

Browse files
author
Tomas Kirda
committed
Call transformResult on the value returned from the server. Fixes devbridge#49
1 parent 52151c2 commit a362ce1

File tree

3 files changed

+66
-23
lines changed

3 files changed

+66
-23
lines changed

readme.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The standard jquery.autocomplete.js file is around 2.7KB when minified via Closu
1515
* `serviceUrl`: Server side URL that provides results for suggestions. Optional if local lookup data is provided.
1616
* `lookup`: Lookup array for the suggestions. It may be array of strings or `suggestion` object literals.
1717
* `suggestion`: An object literal with the following format: `{ value: 'string', data: any }`.
18-
* `lookupFilter`: `function (suggestion, query, queryLowerCase) {}` filter function for local lookups. By default it does partial string match (case insensitive).
18+
* `lookupFilter`: `function (suggestion, query, queryLowerCase) {}` filter function for local lookups. By default it does partial string match (case insensitive).
1919
* `onSelect`: `function (suggestion) {}` Callback function invoked when user selects suggestion
2020
from the list. `this` inside callback refers to input HtmlElement.
2121
* `minChars`: Minimum number of characters required to trigger autosuggest. Default: `1`.
@@ -34,10 +34,10 @@ The standard jquery.autocomplete.js file is around 2.7KB when minified via Closu
3434
* `onSearchComplete`: `function (query) {}` called after ajax response is processed. `this` is bound to input element.
3535
* `tabDisabled`: Default `false`. Set to true to leave the cursor in the input field after the user tabs to select a suggestion.
3636
* `paramName`: Default `query`. The name of the request parameter that contains the query.
37-
* `transformResult`: `function(response) {}` called after the result of the query is ready. Converts the result into response.suggestions format.
38-
* `autoSelectFirst`: if set to `true`, first item will be selected when showing suggestions. Default value `false`.
39-
* `appendTo`: container where suggestions will be appended. Default value `body`. Can be jQuery object, selector or html element. Make sure to set `position: absolute` or `position: relative` for that element.
40-
* `dataType`: type of data returned from server. Either 'text' (default) or 'jsonp', which will cause the autocomplete to use jsonp. You may return a json object in your callback when using jsonp.
37+
* `transformResult`: `function(response, originalQuery) {}` called after the result of the query is ready. Converts the result into response.suggestions format.
38+
* `autoSelectFirst`: if set to `true`, first item will be selected when showing suggestions. Default value `false`.
39+
* `appendTo`: container where suggestions will be appended. Default value `body`. Can be jQuery object, selector or html element. Make sure to set `position: absolute` or `position: relative` for that element.
40+
* `dataType`: type of data returned from server. Either 'text' (default) or 'jsonp', which will cause the autocomplete to use jsonp. You may return a json object in your callback when using jsonp.
4141

4242
##Usage
4343

@@ -115,13 +115,16 @@ you can supply the "paramName" and "transformResult" options:
115115

116116
$('#autocomplete').autocomplete({
117117
paramName: 'searchString',
118-
transformResult: function(response) {
119-
return $.map(response.myData, function(dataItem) {
120-
return {value: dataItem.valueField, data: dataItem.dataField};
121-
});
118+
transformResult: function(response, originalQuery) {
119+
return {
120+
query: originalQuery,
121+
suggestions: $.map(response.myData, function(dataItem) {
122+
return { value: dataItem.valueField, data: dataItem.dataField };
123+
})
124+
};
122125
}
123126
})
124-
127+
125128

126129
Important: query value must match original value in the input
127130
field, otherwise suggestions will not be displayed.

spec/autocompleteBehavior.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,45 @@ describe('Autocomplete', function () {
171171
});
172172
});
173173

174+
it('Should transform results', function () {
175+
var input = document.createElement('input'),
176+
ajaxExecuted = false,
177+
url = '/test-transform',
178+
autocomplete = new $.Autocomplete(input, {
179+
serviceUrl: url,
180+
transformResult: function (result, query) {
181+
return {
182+
query: query,
183+
suggestions: $.map(result.split(','), function (item) {
184+
return { value: item, data: null };
185+
})
186+
};
187+
}
188+
});
189+
190+
$.mockjax({
191+
url: url,
192+
responseTime: 50,
193+
response: function () {
194+
ajaxExecuted = true;
195+
this.responseText = 'Andora,Angola,Argentina';
196+
}
197+
});
198+
199+
input.value = 'A';
200+
autocomplete.onValueChange();
201+
202+
waitsFor(function () {
203+
return ajaxExecuted;
204+
}, 'Ajax call never completed.', 100);
205+
206+
runs(function () {
207+
expect(ajaxExecuted).toBe(true);
208+
expect(autocomplete.suggestions.length).toBe(3);
209+
expect(autocomplete.suggestions[0].value).toBe('Andora');
210+
});
211+
});
212+
174213
it('Should should not preventDefault when tabDisabled is set to false', function () {
175214
var input = document.createElement('input'),
176215
autocomplete = new $.Autocomplete(input, {

src/jquery.autocomplete.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@
9494
return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1;
9595
},
9696
paramName: 'query',
97-
transformResult: function (response) {
98-
return response.suggestions;
97+
transformResult: function (response, originalQuery) {
98+
return typeof response === 'string' ? $.parseJSON(response) : response;
9999
}
100100
};
101101

@@ -408,8 +408,8 @@
408408
data: options.params,
409409
type: options.type,
410410
dataType: options.dataType
411-
}).done(function (txt) {
412-
that.processResponse(txt);
411+
}).done(function (data) {
412+
that.processResponse(data, q);
413413
options.onSearchComplete.call(that.element, q);
414414
});
415415
}
@@ -475,23 +475,24 @@
475475
return suggestions;
476476
},
477477

478-
processResponse: function (text) {
478+
processResponse: function (response, originalQuery) {
479479
var that = this,
480-
response = typeof text == 'string' ? $.parseJSON(text) : text;
480+
options = that.options,
481+
result = that.options.transformResult(response, originalQuery);
481482

482-
response.suggestions = that.verifySuggestionsFormat(that.options.transformResult(response));
483+
result.suggestions = that.verifySuggestionsFormat(result.suggestions);
483484

484485
// Cache results if cache is not disabled:
485-
if (!that.options.noCache) {
486-
that.cachedResponse[response[that.options.paramName]] = response;
487-
if (response.suggestions.length === 0) {
488-
that.badQueries.push(response[that.options.paramName]);
486+
if (!options.noCache) {
487+
that.cachedResponse[result[options.paramName]] = result;
488+
if (result.suggestions.length === 0) {
489+
that.badQueries.push(result[options.paramName]);
489490
}
490491
}
491492

492493
// Display suggestions only if returned query matches current value:
493-
if (response[that.options.paramName] === that.getQuery(that.currentValue)) {
494-
that.suggestions = response.suggestions;
494+
if (result[options.paramName] === that.getQuery(that.currentValue)) {
495+
that.suggestions = result.suggestions;
495496
that.suggest();
496497
}
497498
},

0 commit comments

Comments
 (0)