diff --git a/awesomplete.js b/awesomplete.js
index 396fb711..b98da1e6 100644
--- a/awesomplete.js
+++ b/awesomplete.js
@@ -38,6 +38,7 @@ var _ = function (input, o) {
container: _.CONTAINER,
item: _.ITEM,
replace: _.REPLACE,
+ suggestion: Suggestion,
tabSelect: false
}, o);
@@ -307,7 +308,7 @@ _.prototype = {
this.suggestions = this._list
.map(function(item) {
- return new Suggestion(me.data(item, value));
+ return new me.suggestion(me.data(item, value));
})
.filter(function(item) {
return me.filter(item, value);
diff --git a/index.html b/index.html
index 9676d747..86637d53 100644
--- a/index.html
+++ b/index.html
@@ -304,6 +304,12 @@
Extend
Awesomplete.DATA: Identity function which just returns the original list item. |
+
+ suggestion |
+ Controls the class used to create new Suggestions. |
+ A class that responds to the label, value, and length properties and the toString and valueOf methods. |
+ Suggestion: A basic class, protoyped from String, which provides the requisite functionality. |
+
diff --git a/test/init/optionsSpec.js b/test/init/optionsSpec.js
index fc60997c..705f1015 100644
--- a/test/init/optionsSpec.js
+++ b/test/init/optionsSpec.js
@@ -38,6 +38,10 @@ describe("Constructor options", function () {
it("replaces input value with REPLACE", function () {
expect(this.subject.replace).toEqual(Awesomplete.REPLACE);
});
+
+ it("creates a default Suggestion", function () {
+ expect(this.subject.suggestion.toString()).toMatch(/function Suggestion\(/);
+ });
});
describe("with custom options in constructor", function () {
@@ -77,4 +81,107 @@ describe("Constructor options", function () {
expect(this.subject.autoFirst).toBe(true);
});
});
+
+ describe("with a custom suggestion option", function () {
+ def("element", "#with-data-list");
+
+ function CustomSuggestion1(data) {
+ var o = Array.isArray(data)
+ ? { label: data[0], value: data[1] }
+ : typeof data === "object" && "label" in data && "value" in data ? data : { label: data, value: data };
+
+ this.label = o.label || o.value;
+ this.value = o.value;
+ this.custom = o.label.toUpperCase();
+ }
+
+ Object.defineProperty(CustomSuggestion1.prototype = Object.create(String.prototype), "length", {
+ get: function() { return this.label.length; }
+ });
+
+ CustomSuggestion1.prototype.toString = CustomSuggestion1.prototype.valueOf = function () {
+ return "" + this.label;
+ };
+
+ function CustomSuggestion2(data) {
+ var o = Array.isArray(data)
+ ? { label: data[0], value: data[1] }
+ : typeof data === "object" && "label" in data && "value" in data ? data : { label: data, value: data };
+
+ this.label = o.label || o.value;
+ this.value = o.value;
+ this.custom = o.label.toLowerCase();
+ }
+
+ Object.defineProperty(CustomSuggestion2.prototype = Object.create(String.prototype), "length", {
+ get: function() { return this.label.length; }
+ });
+
+ CustomSuggestion2.prototype.toString = CustomSuggestion2.prototype.valueOf = function () {
+ return "" + this.label;
+ };
+
+ describe("using a class", function () {
+ def("options", function () {
+ return {
+ minChars: 0,
+ filter: function (item) { return item; },
+ sort: $.noop,
+ item: function (suggestion) {
+ var element = document.createElement("li");
+ element.textContent = suggestion.custom;
+
+ return element;
+ },
+ replace: $.noop,
+ suggestion: CustomSuggestion1
+ };
+ });
+
+ it("overrides simple default options", function () {
+ this.subject.evaluate();
+
+ this.subject._list.forEach(function (item, index) {
+ expect(this.subject.ul.children[index].textContent).toEqual(item.label.toUpperCase());
+ }, this);
+ });
+ });
+
+ describe("using a function to return different classes", function () {
+ def("options", function () {
+ return {
+ minChars: 0,
+ filter: function (item) { return item; },
+ sort: $.noop,
+ item: function (suggestion) {
+ var element = document.createElement("li");
+ element.textContent = suggestion.custom;
+
+ return element;
+ },
+ replace: $.noop,
+ suggestion: function (datum) {
+ if (datum.label === "Data") {
+ return new CustomSuggestion1(datum);
+ } else {
+ return new CustomSuggestion2(datum);
+ }
+ }
+ };
+ });
+
+ it("overrides simple default options", function () {
+ this.subject.suggestion = this.subject.suggestion.bind(this.subject);
+ this.subject.evaluate();
+
+ this.subject._list.forEach(function (item, index) {
+ if (item.label === "Data") {
+ expect(this.subject.ul.children[index].textContent).toEqual(item.label.toUpperCase());
+ } else {
+ expect(this.subject.ul.children[index].textContent).toEqual(item.label.toLowerCase());
+ }
+ }, this);
+ });
+ });
+ });
});