Skip to content

Instantly share code, notes, and snippets.

@ribaptista
Created February 17, 2023 14:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ribaptista/635d42fd1a290a26ffe79f165cabe159 to your computer and use it in GitHub Desktop.
Save ribaptista/635d42fd1a290a26ffe79f165cabe159 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>HTML 5 Boilerplate</title>
</head>
<body>
<input type="text" id="message" />
<ul id="suggestions"></ul>
<script>
const users = [
{ name: "john", id: 1 },
{ name: "jane", id: 2 },
{ name: "richard", id: 3 },
{ name: "robert", id: 4 },
];
let suggestions = [];
const input = document.getElementById("message");
document.addEventListener("keydown", (e) => {
if (e.keyCode != 9) return;
if (suggestions.length == 0) {
return;
}
const match = /@([a-z0-9_]*)$/i.exec(
input.value.substring(
0,
getInsertPosition(input.value, input.selectionStart)
)
);
if (!match) {
return;
}
const txt = input.value;
const ins = getInsertPosition(input.value, input.selectionStart);
const add = suggestions[0].name.substring(match[1].length);
input.value = txt.substring(0, ins) + add + " " + txt.substring(ins);
input.selectionStart = input.selectionEnd = ins + add.length + 1;
updateSuggestions("");
e.preventDefault();
});
input.addEventListener("selectionchange", (e) => {
if (input.selectionStart != input.selectionEnd) {
updateSuggestions("");
return;
}
updateSuggestions(
input.value.substring(
0,
getInsertPosition(input.value, input.selectionStart)
)
);
});
function getInsertPosition(txt, cur) {
const before = txt.substring(0, cur);
const after = txt.substring(cur);
return before.length + /^[a-z0-9_]*/.exec(after)[0].length;
}
function updateSuggestions(txt) {
const match = /@([a-z0-9_]*)$/i.exec(txt);
if (!match) {
document.getElementById("suggestions").innerHTML = "";
suggestions = [];
return;
}
const pre = match[1];
const sugs = users.filter(({ name }) => {
return name.indexOf(pre) == 0;
});
suggestions = sugs;
document.getElementById("suggestions").innerHTML = sugs
.map(({ name }) => "<li>" + name + "</li>")
.join("");
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment