- Textarea Smart Auto-Complete Hints là gì
- Quy tắc gợi ý trong Textarea Smart Auto-Complete
- Cấu trúc HTML cho Textarea và vùng gợi ý
- Danh sách gợi ý được định nghĩa trước
- CSS cho Textarea và danh sách gợi ý
- JavaScript để phát hiện trigger và hiển thị gợi ý
- Demo Textarea Smart Auto-Complete Hints
- Mở rộng Textarea Smart Auto-Complete Hints
- Kết luận
Textarea Smart Auto-Complete Hints là gì
Textarea Smart Auto-Complete Hints là một textarea có khả năng:
- Nhận biết khi người dùng gõ một ký tự kích hoạt, ví dụ “/”.
- Đọc đoạn văn bản ngay sau ký tự kích hoạt để xác định từ khóa cần gợi ý.
- Hiển thị danh sách gợi ý bên dưới textarea.
- Cho phép người dùng chọn một gợi ý để tự động thay thế phần đã gõ bằng nội dung hoàn chỉnh hơn.
Cách làm này giúp tăng tốc độ nhập liệu, giảm sai sót và tạo trải nghiệm viết nội dung gần với các ứng dụng hiện đại như Notion, Slack hoặc các trình soạn thảo hỗ trợ slash command.
Quy tắc gợi ý trong Textarea Smart Auto-Complete
Để cơ chế gợi ý hoạt động một cách có logic và dễ kiểm soát, có thể đặt ra các quy tắc đơn giản như sau:
- Chỉ bắt đầu gợi ý khi người dùng gõ ký tự “/” ở đầu dòng hoặc sau dấu cách.
- Phần ký tự ngay sau “/” được xem là từ khóa để lọc danh sách gợi ý.
- Danh sách gợi ý hiển thị phía dưới textarea, chỉ xuất hiện khi có ít nhất một gợi ý khớp.
- Khi người dùng nhấp vào một gợi ý, đoạn “/tukhoa” sẽ được thay bằng nội dung tương ứng do hệ thống định nghĩa trước.
Với cách tổ chức này, Textarea Smart Auto-Complete Hints vẫn đơn giản, dễ bảo trì nhưng đủ linh hoạt để mở rộng số lượng gợi ý trong tương lai.
Cấu trúc HTML cho Textarea và vùng gợi ý
Để triển khai tính năng gợi ý thông minh, cần có:
- Một textarea dùng để nhập nội dung.
- Một vùng chứa danh sách gợi ý nằm ngay bên dưới textarea.
Ví dụ cấu trúc HTML tối giản:
<div class="smart-textarea-wrapper">
<label for="smart-textarea">Nhập nội dung (gõ / để xem gợi ý)</label>
<textarea id="smart-textarea" rows="3" placeholder="Ví dụ: /todo hoặc /note"></textarea>
<div id="smart-hints" class="smart-hints">
<!-- Gợi ý sẽ được JavaScript thêm vào đây -->
</div>
</div>
Vùng gợi ý được đặt trong cùng một wrapper để có thể canh hàng với textarea và dễ dàng định vị bằng CSS.
Danh sách gợi ý được định nghĩa trước
Danh sách gợi ý có thể được khai báo dưới dạng một mảng các đối tượng JavaScript. Mỗi phần tử bao gồm mã lệnh, mô tả ngắn và nội dung sẽ được chèn vào textarea khi người dùng chọn gợi ý.
var HINT_ITEMS = [
{
key: "todo",
label: "Thêm dòng checklist TODO",
insertText: "- [ ] "
},
{
key: "note",
label: "Chèn block ghi chú",
insertText: "Ghi chú: "
},
{
key: "quote",
label: "Chèn trích dẫn",
insertText: "> Trích dẫn..."
}
];
Cấu trúc này cho phép dễ dàng thêm hoặc bớt gợi ý mà không cần thay đổi logic xử lý chính.
CSS cho Textarea và danh sách gợi ý
Để gợi ý hiển thị rõ ràng, có thể sử dụng một số quy tắc CSS đơn giản:
.smart-textarea-wrapper {
max-width: 520px;
margin: 16px 0;
position: relative;
}
.smart-textarea-wrapper label {
display: block;
font-size: 14px;
font-weight: 600;
margin-bottom: 6px;
}
.smart-textarea-wrapper textarea {
width: 100%;
padding: 8px;
box-sizing: border-box;
font-family: system-ui, sans-serif;
resize: vertical;
}
/* Hộp gợi ý */
.smart-hints {
position: absolute;
left: 0;
right: 0;
top: 100%;
margin-top: 4px;
background: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 4px;
box-shadow: 0 6px 20px rgba(15, 23, 42, 0.12);
font-size: 13px;
display: none;
z-index: 20;
}
.smart-hints.active {
display: block;
}
.smart-hints-item {
padding: 6px 10px;
cursor: pointer;
}
.smart-hints-item:hover {
background: #f3f4f6;
}
Trong ví dụ này, danh sách gợi ý được thiết kế giống một dropdown nhỏ nằm sát ngay dưới textarea, xuất hiện khi có gợi ý phù hợp.
JavaScript để phát hiện trigger và hiển thị gợi ý
Đoạn JavaScript dưới đây mô tả đầy đủ luồng xử lý:
- Lắng nghe sự kiện
inputtrên textarea. - Xác định vị trí con trỏ hiện tại trong textarea.
- Tìm ký tự “/” gần nhất trước con trỏ và lấy từ khóa gợi ý.
- Lọc danh sách gợi ý theo từ khóa, cập nhật danh sách hiển thị.
(function() {
var HINT_ITEMS = [
{ key: "todo", label: "Thêm dòng checklist TODO", insertText: "- [ ] " },
{ key: "note", label: "Chèn block ghi chú", insertText: "Ghi chú: " },
{ key: "quote", label: "Chèn trích dẫn", insertText: "> Trích dẫn..." }
];
var textarea = document.getElementById("smart-textarea");
var hintsBox = document.getElementById("smart-hints");
var currentTriggerIndex = -1;
function findTriggerInfo(value, caretPos) {
var before = value.slice(0, caretPos);
var lastNewLine = before.lastIndexOf("\n");
var lastSpace = before.lastIndexOf(" ");
var startBoundary = Math.max(lastNewLine, lastSpace);
var triggerIndex = before.lastIndexOf("/", caretPos);
if (triggerIndex === -1 || triggerIndex <= startBoundary) {
return null;
}
var keyword = before.slice(triggerIndex + 1);
return {
triggerIndex: triggerIndex,
keyword: keyword
};
}
function renderHints(items) {
if (!items.length) {
hintsBox.classList.remove("active");
hintsBox.innerHTML = "";
return;
}
var html = items.map(function(item) {
return '<div class="smart-hints-item" data-key="' + item.key + '">' +
'<strong>/' + item.key + '</strong> - ' + item.label +
"</div>";
}).join("");
hintsBox.innerHTML = html;
hintsBox.classList.add("active");
}
function handleInput() {
var value = textarea.value;
var caretPos = textarea.selectionStart;
var info = findTriggerInfo(value, caretPos);
if (!info) {
currentTriggerIndex = -1;
renderHints([]);
return;
}
currentTriggerIndex = info.triggerIndex;
var keyword = info.keyword.toLowerCase();
var filtered = HINT_ITEMS.filter(function(item) {
return item.key.indexOf(keyword) === 0;
});
renderHints(filtered);
}
function insertHint(insertText) {
var value = textarea.value;
var caretPos = textarea.selectionStart;
if (currentTriggerIndex === -1) {
return;
}
var before = value.slice(0, currentTriggerIndex);
var after = value.slice(caretPos);
var result = before + insertText + after;
textarea.value = result;
var newCaretPos = before.length + insertText.length;
textarea.focus();
textarea.setSelectionRange(newCaretPos, newCaretPos);
hintsBox.classList.remove("active");
hintsBox.innerHTML = "";
currentTriggerIndex = -1;
}
hintsBox.addEventListener("click", function(e) {
var itemEl = e.target.closest(".smart-hints-item");
if (!itemEl) return;
var key = itemEl.getAttribute("data-key");
var hint = HINT_ITEMS.find(function(h) { return h.key === key; });
if (hint) {
insertHint(hint.insertText);
}
});
document.addEventListener("click", function(e) {
if (!hintsBox.contains(e.target) && e.target !== textarea) {
hintsBox.classList.remove("active");
hintsBox.innerHTML = "";
currentTriggerIndex = -1;
}
});
textarea.addEventListener("input", handleInput);
})();
Với đoạn mã này, textarea sẽ tự động hiển thị gợi ý mỗi khi người dùng gõ “/” và tiếp tục nhập từ khóa khớp với các gợi ý đã định nghĩa trong mảng HINT_ITEMS.
Demo Textarea Smart Auto-Complete Hints
Ví dụ dưới đây minh họa một Textarea Smart Auto-Complete Hints đang hoạt động. Người dùng có thể gõ “/todo”, “/note” hoặc “/quote” để xem gợi ý và nhấp chọn để chèn nhanh nội dung tương ứng.
Mở rộng Textarea Smart Auto-Complete Hints
Từ phiên bản cơ bản, Textarea Smart Auto-Complete Hints có thể mở rộng theo nhiều hướng:
- Hỗ trợ nhiều ký tự kích hoạt khác nhau, ví dụ “/” cho lệnh và “@” cho nhắc tới người dùng.
- Bổ sung điều hướng bằng bàn phím (phím mũi tên và Enter) cho danh sách gợi ý.
- Hiển thị mô tả chi tiết hơn cho từng gợi ý, bao gồm icon hoặc nhãn phụ.
- Tích hợp với dữ liệu động từ phía máy chủ để gợi ý nội dung theo ngữ cảnh thực tế.
Kết luận
Textarea Smart Auto-Complete Hints là một bước nâng cấp nhỏ nhưng đem lại trải nghiệm nhập liệu hiện đại và hiệu quả hơn cho người dùng.
Bằng cách kết hợp HTML, CSS và JavaScript, đồng thời định nghĩa rõ quy tắc kích hoạt và bộ gợi ý, có thể xây dựng một hệ thống gợi ý nhẹ, dễ triển khai và dễ bảo trì.
Tính năng này phù hợp cho các ứng dụng ghi chú, hệ thống soạn thảo tài liệu, công cụ viết nội dung hoặc bất kỳ nơi nào cần tăng tốc và chuẩn hóa quá trình nhập liệu.
Bình luận