From b445ec6ade27b92979d5681a814eae5119c2f29c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Andre=CC=81s=20Correa?= Date: Sat, 4 Jan 2014 11:37:20 -0500 Subject: [PATCH 1/8] added keyPath option and updated readme keyPath option specifies the key in the response where the results are. Also added a little usage example on readme --- readme.md | 9 +++++++++ spec/autocompleteBehavior.js | 36 ++++++++++++++++++++++++++++++++++++ src/jquery.autocomplete.js | 3 ++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index b3ddf33c..3e867d0f 100644 --- a/readme.md +++ b/readme.md @@ -13,6 +13,7 @@ The standard jquery.autocomplete.js file is around 2.7KB when minified via Closu * Sets up autocomplete for input field(s). * `options`: An object literal which defines the settings to use for the autocomplete plugin. * `serviceUrl`: Server side URL or callback function that returns serviceUrl string. Optional if local lookup data is provided. + * `keyPath`: (by default `suggestions`). The key of the response where the array of results is. * `lookup`: Lookup array for the suggestions. It may be array of strings or `suggestion` object literals. * `suggestion`: An object literal with the following format: `{ value: 'string', data: any }`. * `lookupFilter`: `function (suggestion, query, queryLowerCase) {}` filter function for local lookups. By default it does partial string match (case insensitive). @@ -152,6 +153,14 @@ you can supply the "paramName" and "transformResult" options: } }) +If your ajax service responds with a key different than `suggestions`, you can use `keyPath`: + +For example, if your server responds with: `{items: [{value: 'Item 1'}, {value: 'Item 2'}]}`: + + $('#autocomplete').autocomplete({ + keyPath: "items" + }) + ##License diff --git a/spec/autocompleteBehavior.js b/spec/autocompleteBehavior.js index 80718cfa..43578798 100644 --- a/spec/autocompleteBehavior.js +++ b/spec/autocompleteBehavior.js @@ -654,4 +654,40 @@ describe('Autocomplete', function () { expect(ajaxCount).toBe(2); }); }); + + it('Should accept the key as an option', function () { + var input = $(''), + instance, + ajaxExecuted, + serviceUrl = "/items.json"; + + + input.autocomplete({ + serviceUrl: serviceUrl, + keyPath: "items" + }); + + $.mockjax({ + url: serviceUrl, + responseTime: 5, + response: function (settings) { + ajaxExecuted = true; + var response = { + items: [{value: "Item 1", id: 1}, {value: "Item 2", id: 2}, {value: "Item 3", id: 3}, {value: "Item 4", id: 4}] + }; + this.responseText = JSON.stringify(response); + } + }); + + input.val("item"); + instance = input.autocomplete(); + instance.onValueChange(); + + waits(10); + + runs(function() { + expect(ajaxExecuted).toBeTruthy(); + expect(instance.suggestions.length).toBe(4); + }); + }); }); diff --git a/src/jquery.autocomplete.js b/src/jquery.autocomplete.js index f2114bf5..d3d70925 100644 --- a/src/jquery.autocomplete.js +++ b/src/jquery.autocomplete.js @@ -57,6 +57,7 @@ appendTo: 'body', serviceUrl: null, lookup: null, + keyPath: "suggestions", onSelect: null, width: 'auto', minChars: 1, @@ -648,7 +649,7 @@ var that = this, options = that.options; - result.suggestions = that.verifySuggestionsFormat(result.suggestions); + result.suggestions = that.verifySuggestionsFormat(result[options.keyPath]); // Cache results if cache is not disabled: if (!options.noCache) { From 0a8cde553918ca48011566847125ac1294012507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Andre=CC=81s=20Correa?= Date: Mon, 6 Jan 2014 00:47:24 -0500 Subject: [PATCH 2/8] beginning specs of `valueKey` --- spec/autocompleteBehavior.js | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/spec/autocompleteBehavior.js b/spec/autocompleteBehavior.js index 43578798..5f92aa19 100644 --- a/spec/autocompleteBehavior.js +++ b/spec/autocompleteBehavior.js @@ -690,4 +690,40 @@ describe('Autocomplete', function () { expect(instance.suggestions.length).toBe(4); }); }); + + it('Should accept valueKey as an aoption', function () { + var input = $(''), + instance, + ajaxExecuted, + serviceUrl = "/items.json"; + + input.autocomplete({ + serviceUrl: serviceUrl, + keyPath: "items", + valueKey: "nombre" + }); + + $.mockjax({ + url: serviceUrl, + responseTime: 5, + response: function (settings) { + ajaxExecuted = true; + var response = { + items: [{nombre: "Item 1", id: 1}, {nombre: "Item 2", id: 2}, {nombre: "Item 3", id: 3}] + }; + this.responseText = JSON.stringify(response); + } + }); + + input.val("item"); + instance = input.autocomplete(); + instance.onValueChange(); + + waits(10); + + runs(function () { + expect(ajaxExecuted).toBeTruthy(); + expect(instance.suggestions.length).toBe(3); + }); + }) }); From 988cc5f93cd8803f4d4af2be59115af9fa8442f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Andre=CC=81s=20Correa?= Date: Mon, 6 Jan 2014 01:10:27 -0500 Subject: [PATCH 3/8] typo --- spec/autocompleteBehavior.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/autocompleteBehavior.js b/spec/autocompleteBehavior.js index 5f92aa19..e3b15c3e 100644 --- a/spec/autocompleteBehavior.js +++ b/spec/autocompleteBehavior.js @@ -691,7 +691,7 @@ describe('Autocomplete', function () { }); }); - it('Should accept valueKey as an aoption', function () { + it('Should accept valueKey as an option', function () { var input = $(''), instance, ajaxExecuted, From a074f5038e406900033369cb75f1ac31af9e5b0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Andre=CC=81s=20Correa?= Date: Mon, 6 Jan 2014 01:16:18 -0500 Subject: [PATCH 4/8] fixed test --- spec/autocompleteBehavior.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/autocompleteBehavior.js b/spec/autocompleteBehavior.js index e3b15c3e..3fdf22d7 100644 --- a/spec/autocompleteBehavior.js +++ b/spec/autocompleteBehavior.js @@ -695,7 +695,7 @@ describe('Autocomplete', function () { var input = $(''), instance, ajaxExecuted, - serviceUrl = "/items.json"; + serviceUrl = "/dogs.json"; input.autocomplete({ serviceUrl: serviceUrl, @@ -709,13 +709,13 @@ describe('Autocomplete', function () { response: function (settings) { ajaxExecuted = true; var response = { - items: [{nombre: "Item 1", id: 1}, {nombre: "Item 2", id: 2}, {nombre: "Item 3", id: 3}] + items: [{nombre: "Dog 1", id: 1}, {nombre: "Dog 2", id: 2}, {nombre: "Dog 3", id: 3}, {nombre: "Dog 4", id: 4}, {nombre: "Dog 5", id: 5}] }; this.responseText = JSON.stringify(response); } }); - input.val("item"); + input.val("Dog"); instance = input.autocomplete(); instance.onValueChange(); @@ -723,7 +723,7 @@ describe('Autocomplete', function () { runs(function () { expect(ajaxExecuted).toBeTruthy(); - expect(instance.suggestions.length).toBe(3); + expect(instance.suggestions.length).toBe(5); }); }) }); From 6272ce2ce1d993b94ad5c7dd2d0130bd38d13273 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Andre=CC=81s=20Correa?= Date: Mon, 6 Jan 2014 01:16:29 -0500 Subject: [PATCH 5/8] implemented valueKey --- src/jquery.autocomplete.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/jquery.autocomplete.js b/src/jquery.autocomplete.js index d3d70925..7ffa6242 100644 --- a/src/jquery.autocomplete.js +++ b/src/jquery.autocomplete.js @@ -58,6 +58,7 @@ serviceUrl: null, lookup: null, keyPath: "suggestions", + valueKey: "value", onSelect: null, width: 'auto', minChars: 1, @@ -118,10 +119,10 @@ $.Autocomplete = Autocomplete; - Autocomplete.formatResult = function (suggestion, currentValue) { + Autocomplete.formatResult = function (suggestion, currentValue, context) { var pattern = '(' + utils.escapeRegExChars(currentValue) + ')'; - return suggestion.value.replace(new RegExp(pattern, 'gi'), '$1<\/strong>'); + return suggestion[context.options.valueKey].replace(new RegExp(pattern, 'gi'), '$1<\/strong>'); }; Autocomplete.prototype = { @@ -429,7 +430,7 @@ queryLowerCase = query.toLowerCase(); $.each(that.suggestions, function (i, suggestion) { - if (suggestion.value.toLowerCase() === queryLowerCase) { + if (suggestion[that.options.valueKey].toLowerCase() === queryLowerCase) { index = i; return false; } @@ -571,7 +572,7 @@ // Build suggestions inner HTML: $.each(that.suggestions, function (i, suggestion) { - html += '
' + formatResult(suggestion, value) + '
'; + html += '
' + formatResult(suggestion, value, that) + '
'; }); // If width is auto, adjust width before displaying suggestions, @@ -611,7 +612,7 @@ } $.each(that.suggestions, function (i, suggestion) { - var foundMatch = suggestion.value.toLowerCase().indexOf(value) === 0; + var foundMatch = suggestion[that.options.valueKey].toLowerCase().indexOf(value) === 0; if (foundMatch) { bestMatch = suggestion; } @@ -625,7 +626,7 @@ var hintValue = '', that = this; if (suggestion) { - hintValue = that.currentValue + suggestion.value.substr(that.currentValue.length); + hintValue = that.currentValue + suggestion[that.options.valueKey].substr(that.currentValue.length); } if (that.hintValue !== hintValue) { that.hintValue = hintValue; @@ -751,7 +752,7 @@ $(that.suggestionsContainer).scrollTop(offsetTop - that.options.maxHeight + heightDelta); } - that.el.val(that.getValue(that.suggestions[index].value)); + that.el.val(that.getValue(that.suggestions[index].this[valueKey])); that.signalHint(null); }, @@ -760,7 +761,7 @@ onSelectCallback = that.options.onSelect, suggestion = that.suggestions[index]; - that.currentValue = that.getValue(suggestion.value); + that.currentValue = that.getValue(suggestion[that.valueKey]); that.el.val(that.currentValue); that.signalHint(null); that.suggestions = []; From f37632e26a600a262927644e4902561e6fb2715a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Andre=CC=81s=20Correa?= Date: Mon, 6 Jan 2014 01:19:11 -0500 Subject: [PATCH 6/8] updated readme to new implementation --- readme.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 3e867d0f..5486b04a 100644 --- a/readme.md +++ b/readme.md @@ -14,6 +14,7 @@ The standard jquery.autocomplete.js file is around 2.7KB when minified via Closu * `options`: An object literal which defines the settings to use for the autocomplete plugin. * `serviceUrl`: Server side URL or callback function that returns serviceUrl string. Optional if local lookup data is provided. * `keyPath`: (by default `suggestions`). The key of the response where the array of results is. + * `valueKey`: (by default `value`). The key in the server response. (If your response has a different format). * `lookup`: Lookup array for the suggestions. It may be array of strings or `suggestion` object literals. * `suggestion`: An object literal with the following format: `{ value: 'string', data: any }`. * `lookupFilter`: `function (suggestion, query, queryLowerCase) {}` filter function for local lookups. By default it does partial string match (case insensitive). @@ -153,12 +154,13 @@ you can supply the "paramName" and "transformResult" options: } }) -If your ajax service responds with a key different than `suggestions`, you can use `keyPath`: +If your ajax service responds with a key different than `suggestions`, you can use `keyPath` option. If the *suggestions* key to display is other than `value`, you can use `valueKey` option: -For example, if your server responds with: `{items: [{value: 'Item 1'}, {value: 'Item 2'}]}`: +For example, if your server responds with: `{items: [{name: 'Item 1'}, {name: 'Item 2'}]}` you should use the following options: $('#autocomplete').autocomplete({ - keyPath: "items" + keyPath: "items", + valueKey: "name" }) From 06f090225b8ce826b1daf3d8ca2d8e5596caa43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Andre=CC=81s=20Correa?= Date: Mon, 6 Jan 2014 01:38:00 -0500 Subject: [PATCH 7/8] bugfix --- src/jquery.autocomplete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.autocomplete.js b/src/jquery.autocomplete.js index 7ffa6242..c9f9a0d9 100644 --- a/src/jquery.autocomplete.js +++ b/src/jquery.autocomplete.js @@ -761,7 +761,7 @@ onSelectCallback = that.options.onSelect, suggestion = that.suggestions[index]; - that.currentValue = that.getValue(suggestion[that.valueKey]); + that.currentValue = that.getValue(suggestion[that.options.valueKey]); that.el.val(that.currentValue); that.signalHint(null); that.suggestions = []; From 50b2c328d67af35c28f82e6cba66644eb6c5c429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Andre=CC=81s=20Correa?= Date: Mon, 6 Jan 2014 13:01:14 -0500 Subject: [PATCH 8/8] bugfix --- src/jquery.autocomplete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jquery.autocomplete.js b/src/jquery.autocomplete.js index c9f9a0d9..6bace09a 100644 --- a/src/jquery.autocomplete.js +++ b/src/jquery.autocomplete.js @@ -752,7 +752,7 @@ $(that.suggestionsContainer).scrollTop(offsetTop - that.options.maxHeight + heightDelta); } - that.el.val(that.getValue(that.suggestions[index].this[valueKey])); + that.el.val(that.getValue(that.suggestions[index][that.options.valueKey])); that.signalHint(null); },