Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various list data formats and separate title/value #16851

Closed
61 changes: 43 additions & 18 deletions awesomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ var _ = function (input, o) {
autoFirst: false,
filter: _.FILTER_CONTAINS,
sort: _.SORT_BYLENGTH,
data: _.DATA,
item: _.ITEM,
replace: _.REPLACE
}, o);
Expand Down Expand Up @@ -183,18 +184,22 @@ _.prototype = {
$.fire(this.input, "awesomplete-highlight");
},

select: function (selected, origin) {
selected = selected || this.ul.children[this.index];
select: function (selected, originalTarget) {
if (selected) {
this.index = $.siblingIndex(selected);
} else {
selected = this.ul.children[this.index];
}

if (selected) {
var allowed = $.fire(this.input, "awesomplete-select", {
text: selected.textContent,
data: this.suggestions[$.siblingIndex(selected)],
origin: origin || selected
text: this.suggestions[this.index],
data: this.suggestions[this.index],
originalTarget: originalTarget || selected
});

if (allowed) {
this.replace(selected.textContent);
this.replace(this.suggestions[this.index]);
this.close();
$.fire(this.input, "awesomplete-selectcomplete");
}
Expand All @@ -211,14 +216,17 @@ _.prototype = {
this.ul.innerHTML = "";

this.suggestions = this._list
.filter(function(item) {
return me.filter(item, value);
.map(function(item) {
return new Suggestion(me.data(item, value));
})
.filter(function(data) {
return me.filter(data, value);
})
.sort(this.sort)
.slice(0, this.maxItems);

this.suggestions.forEach(function(text) {
me.ul.appendChild(me.item(text, value));
this.suggestions.forEach(function(data) {
me.ul.appendChild(me.item(data, value));
});

if (this.ul.children.length === 0) {
Expand All @@ -237,12 +245,12 @@ _.prototype = {

_.all = [];

_.FILTER_CONTAINS = function (text, input) {
return RegExp($.regExpEscape(input.trim()), "i").test(text);
_.FILTER_CONTAINS = function (data, input) {
return RegExp($.regExpEscape(input.trim()), "i").test(data);
};

_.FILTER_STARTSWITH = function (text, input) {
return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text);
_.FILTER_STARTSWITH = function (data, input) {
return RegExp("^" + $.regExpEscape(input.trim()), "i").test(data);
};

_.SORT_BYLENGTH = function (a, b) {
Expand All @@ -253,20 +261,37 @@ _.SORT_BYLENGTH = function (a, b) {
return a < b? -1 : 1;
};

_.ITEM = function (text, input) {
var html = input === '' ? text : text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>");
_.ITEM = function (data, input) {
var html = input === '' ? data : data.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>");
return $.create("li", {
innerHTML: html,
"aria-selected": "false"
});
};

_.REPLACE = function (text) {
this.input.value = text;
_.REPLACE = function (data) {
this.input.value = data.value;
};

/* eslint-disable no-unused-vars */
_.DATA = function (data, input) {
return data;
};

// Private functions

// List item data shim for 1.x API backward compatibility
function Suggestion(data) {
var o = Array.isArray(data) ? { label: data[0], value: data[1] } : typeof data === "object" ? data : { label: data, value: data };

this.label = o.label;
this.value = o.value;
}
Suggestion.prototype = new String;
Suggestion.prototype.toString = Suggestion.prototype.valueOf = function () {
return this.label;
};

function configure(instance, properties, o) {
for (var i in properties) {
var initial = properties[i],
Expand Down
16 changes: 5 additions & 11 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -334,18 +334,12 @@ <h2>E-mail autocomplete</h2>
<label>Type an email: <input type="email"></label>
<pre class="language-markup"><code>&lt;input type="email" /></code></pre>
<pre class="language-javascript"><code><script>new Awesomplete($('input[type="email"]'), {
list: ["@aol.com", "@att.net", "@comcast.net", "@facebook.com", "@gmail.com", "@gmx.com", "@googlemail.com", "@google.com", "@hotmail.com", "@hotmail.co.uk", "@mac.com", "@me.com", "@mail.com", "@msn.com", "@live.com", "@sbcglobal.net", "@verizon.net", "@yahoo.com", "@yahoo.co.uk"],
item: function(text, input) {
var newText = input.slice(0, input.indexOf("@")) + text;

return Awesomplete.$.create("li", {
innerHTML: newText.replace(RegExp(input.trim(), "gi"), "<mark>$&</mark>"),
"aria-selected": "false"
});
list: ["aol.com", "att.net", "comcast.net", "facebook.com", "gmail.com", "gmx.com", "googlemail.com", "google.com", "hotmail.com", "hotmail.co.uk", "mac.com", "me.com", "mail.com", "msn.com", "live.com", "sbcglobal.net"],
data: function (text, input) {
var newText = input.slice(0, input.indexOf("@")) + "@" + text;
return newText;
},
filter: function(text, input) {
return RegExp("^" + Awesomplete.$.regExpEscape(input.replace(/^.+?(?=@)/, ''), "i")).test(text);
}
filter: Awesomplete.FILTER_STARTSWITH
});</script></code></pre>
</section>

Expand Down
6 changes: 3 additions & 3 deletions test/api/selectSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ describe("awesomplete.select", function () {

expect(handler).toHaveBeenCalledWith(
jasmine.objectContaining({
text: expectedTxt,
data: expectedTxt,
origin: this.selectArgument || this.subject.ul.children[0]
text: jasmine.objectContaining({ label: expectedTxt, value: expectedTxt }),
data: jasmine.objectContaining({ label: expectedTxt, value: expectedTxt }),
originalTarget: this.selectArgument || this.subject.ul.children[0]
})
);
});
Expand Down
2 changes: 1 addition & 1 deletion test/static/replaceSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ describe("Awesomplete.REPLACE", function () {
def("instance", function() { return { input: { value: "initial" } } });

it("replaces input value", function () {
this.subject.call(this.instance, "JavaScript");
this.subject.call(this.instance, { value: "JavaScript" });
expect(this.instance.input.value).toBe("JavaScript");
});
});