This repository has been archived by the owner on Jun 1, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
autocomplete-lines-starting-with-digits.html
200 lines (171 loc) · 5.67 KB
/
autocomplete-lines-starting-with-digits.html
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
---
layout: bare
title: EditDidWhat: <textarea /> input with basic inline autocomplete for even lines starting with digits
---
<h1>
<a href="https://github.com/joelpurra/editdidwhat">EditDidWhat</a>: <textarea
/> input with basic inline autocomplete
</h1>
<p>
A listener will wait for user input in the textarea. For demonstration purposes,
only every other row autocompletes. Enter anything on odd lines (no autocomplete),
try starting even lines with digits (names will autocomplete).
</p>
<ul>
<li>Using <a href="http://jquery.com/">jQuery</a> to set event listeners.</li>
<li>Using <a href="http://code.google.com/p/jcaret/">jQuery Caret (jCaret) plugin</a>
to select the autocompleted text.</li>
</ul>
<fieldset>
<legend>Input with basic inline autocomplete</legend>
<textarea id="example-input" cols="50" rows="10"></textarea>
</fieldset>
<script src="../src/editdidwhat.joelpurra.js"></script>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="http://jcaret.googlecode.com/files/jquery.caret.1.02.js"></script>
<script>
//<![CDATA[
var
startsWithDigits = /^(\d+)/,
names = "Alfred Baltsar Camilla Diana Erland Frideborg Gunnar Hanna Ivar Jan".split(/\s+/);
// Listen on keyup to get the new value in the textarea
$("#example-input")
.on("keyup change", function (event)
{
// Check changes and autocomplete
autocompleteDigits($(this));
})
.on("keydown", function (event)
{
// If there is a selection (from the autocomplete), skip it when using enter or tab
return skipSelectionIfSkipKey(event, $(this));
});
// Check for digits on every other line, and autocomplete the line with names
function autocompleteDigits($textarea)
{
var
previous,
current,
change,
diffIndex,
lastDiffIndex,
diffLineNumber,
lastDiffLineNumber,
isOneLineEdit,
diffLine,
diffLineStart,
diffLineEnd,
digits,
autocompleteWith,
autocompleted;
// Previous value is stored on the <textarea /> element
previous = $textarea.data().previousValue || "";
current = $textarea.val();
$textarea.data({
previousValue: current
});
// Don't act on all sorts of changes
change = EditDidWhat.detectChange(previous, current);
if (!(change === EditDidWhat.StatusInsert
|| change === EditDidWhat.StatusReplace
|| change === EditDidWhat.StatusSplice
|| change === EditDidWhat.StatusAppended))
{
return;
}
// Use EditDidWhat do find where the changes were made
diffIndex = EditDidWhat.findDifferenceIndex(previous, current);
diffLineNumber = EditDidWhat.getLineNumberAt(current, diffIndex);
// Theses statuses can have changes in the middle of the current value
// - need to check from the front and the back to see where the changes
// have occured. If they are on two different lines, don't do anything.
if (change === EditDidWhat.StatusInsert
|| change === EditDidWhat.StatusReplace
|| change === EditDidWhat.StatusSplice)
{
lastDiffIndexAlignRight = EditDidWhat.findLastDifferenceIndexAlignRight(previous, current);
lastDiffLineNumber = EditDidWhat.getLineNumberAt(current, Math.min(current.length - 1, lastDiffIndexAlignRight));
isOneLineEdit = (diffLineNumber === lastDiffLineNumber);
}
else
{
isOneLineEdit = true;
}
// Don't act if
// the change is on an odd (which is even in 0-indexed)
// or affects several lines
// or was a linebreak
if ((diffLineNumber % 2) === 0
|| !isOneLineEdit
|| current.charAt(diffIndex) === '\n')
{
return;
}
// The full contents of the line that had changes
diffLine = EditDidWhat.getLine(current, diffLineNumber);
// Only do autocomplete if the line starts with digits
if (startsWithDigits.test(diffLine))
{
startsWithDigits.exec(diffLine);
digits = RegExp.$1;
// Get data based on the input on the line
// Digits could be zipcodes, product codes or something in another format,
// like mail addresses, usernames, filenames
autocompleteWith = getNamesFromDigits(digits);
// This is the autocomplete; add names after the digits
autocompleted = EditDidWhat.replaceLine(current, diffLineNumber, digits + " " + autocompleteWith);
// Get line bounds to select the text below
diffLineStart = EditDidWhat.getLineStart(autocompleted, diffLineNumber);
diffLineEnd = EditDidWhat.getLineEnd(autocompleted, diffLineNumber);
// Update the textarea
$textarea.val(autocompleted);
// Select the autocompleted text to let the user continue typing digits
$textarea.caret(diffLineStart + digits.length, diffLineEnd);
// Depending on the changes made, optionally alert other listeners
$textarea.change();
}
}
// If there is a selection (from the autocomplete), skip it when using enter or tab
function skipSelectionIfSkipKey(event, $textarea)
{
var
start = $textarea.caret().start,
end = $textarea.caret().end;
if (isAutocompleteSkippableKeycode(event.which)
&& 0 <= start
&& start < end)
{
event.preventDefault();
$textarea.caret(end, end);
return false;
}
}
// Multiple digits will be autocompleted to multiple names
function getNamesFromDigits(digits)
{
var
i,
digit,
output = [];
for (i = 0; i < digits.length; i += 1)
{
digit = parseInt(digits.charAt(i));
output.push(names[digit]);
}
return output.join(", ");
}
// Check if key code means selection should be skipped
function isAutocompleteSkippableKeycode(keycode)
{
// Keys from
// https://developer.mozilla.org/en/DOM/KeyboardEvent#Virtual_key_codes
var
DOM_VK_TAB = 9,
DOM_VK_RETURN = 13,
DOM_VK_ENTER = 14;
return keycode === DOM_VK_TAB
|| keycode === DOM_VK_RETURN
|| keycode === DOM_VK_ENTER;
}
//]]>
</script>