-
Notifications
You must be signed in to change notification settings - Fork 3
/
fuzzy-autocomplete.js
90 lines (90 loc) · 3.28 KB
/
fuzzy-autocomplete.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* Written by Alex Jiao
* Usage: fuzzyAutocomplete($('#your-input-element'), ['data1', 'data2']);
* fuzzyAutocomplete($('#your-input-element'), '/javascripts/data.json');
*/
function fuzzyAutocomplete(input, data) {
var dataList = [];
// Check if data source is array or string type, otherwise return
if (Array.isArray(data)) {
dataList = dataList.concat(data);
} else if (typeof data === 'string' || data instanceof String) {
$.ajax({
url: data,
type: 'GET',
success: function(data) {
data.forEach(function(item) {
dataList.push(item);
});
}
});
} else {
return;
}
// Fuzzy matching with regex
var matchData = function(input, dataList) {
var reg = new RegExp(input.split('').join('\\w*').replace(/\W/, ""), 'i');
return dataList.filter(function(data) {
if (data.match(reg)) {
return data;
}
});
};
// Change input value upon keyup
var changeInput = function(input, dataList) {
var val = input.val();
var inputAncestor = input.parent();
var res = inputAncestor.find('.fuzzy-autocomplete-result');
while(res.length == 0) {
inputAncestor = inputAncestor.parent();
res = inputAncestor.find('.fuzzy-autocomplete-result');
}
res.empty().hide();
var autoCompleteResult = matchData(val, dataList);
if (val == "" || autoCompleteResult.length == 0) {
return;
}
autoCompleteResult.forEach(function(e) {
var p = $('<p />');
p.css({
'margin': '0px',
'padding-left': parseInt(input.css('padding-left'),10) + parseInt(input.css('border-left-width'),10)
});
p.text(e);
p.click(function() {
input.val(p.text());
res.empty().hide();
})
p.mouseenter(function() {
$(this).css("background-color", "#BA9EB0");
}).mouseleave(function() {
$(this).css("background-color", "white");
});
res.append(p);
});
res.css({
'left': input.position().left,
'width': input.width() + parseFloat(input.css('padding-left'),10) + parseInt(input.css('border-left-width'),10) + 1,
'position': 'absolute',
'background-color': "white",
'border': '1px solid #dddddd',
'max-height': '150px',
'overflow': 'scroll',
'overflow-x': 'hidden',
'font-family': input.css('font-family'),
'font-size' : input.css('font-size'),
'z-index' : '10'
}).insertAfter(input).show();
};
// Create a div for collecting the results, and a container for enclosing the input element and result div
var res = $("<div class='fuzzy-autocomplete-result' />");
res.insertAfter(input);
input.keyup(function() {
changeInput(input, dataList);
});
// Hide result div upon clicking anywhere outside the div
$(document).click(function(event) {
if (!$(event.target).closest('.fuzzy-autocomplete-result').length) {
res.empty().hide();
}
});
}