Admin grades: comment autocomplete by substring, larger grade dialog
This commit is contained in:
@@ -54,6 +54,81 @@ function csRow(text, tone) {
|
||||
row.appendChild(sel);
|
||||
row.appendChild(rm);
|
||||
box.appendChild(row);
|
||||
|
||||
attachCommentAutocomplete(inp);
|
||||
}
|
||||
|
||||
/* ---------- Автодополнение комментариев ---------- *
|
||||
* При фокусе/вводе запрашивает ранее введённые комментарии (подстрока, без регистра),
|
||||
* отсортированные по частоте; выбор подставляет текст и «тон». */
|
||||
|
||||
var AC_TIMER = null;
|
||||
|
||||
function attachCommentAutocomplete(input) {
|
||||
var list = document.createElement('div');
|
||||
list.className = 'ac-list';
|
||||
list.hidden = true;
|
||||
input.parentNode.appendChild(list);
|
||||
|
||||
var active = -1;
|
||||
|
||||
function hide() {
|
||||
list.hidden = true;
|
||||
active = -1;
|
||||
}
|
||||
|
||||
function render(items) {
|
||||
if (document.activeElement !== input) return;
|
||||
if (!Array.isArray(items) || !items.length) {
|
||||
hide();
|
||||
return;
|
||||
}
|
||||
list.innerHTML = '';
|
||||
items.forEach(function (item) {
|
||||
var row = document.createElement('div');
|
||||
row.className = 'ac-item';
|
||||
row.textContent = item.text;
|
||||
row.addEventListener('mousedown', function (event) {
|
||||
event.preventDefault();
|
||||
input.value = item.text;
|
||||
var tone = input.parentNode.querySelector('.cs-tone');
|
||||
if (tone && item.tone) tone.value = item.tone;
|
||||
hide();
|
||||
});
|
||||
list.appendChild(row);
|
||||
});
|
||||
list.hidden = false;
|
||||
active = -1;
|
||||
}
|
||||
|
||||
function load() {
|
||||
clearTimeout(AC_TIMER);
|
||||
AC_TIMER = setTimeout(function () {
|
||||
fetch('/admin/comment-templates?q=' + encodeURIComponent(input.value.trim()))
|
||||
.then(function (r) { return r.ok ? r.json() : []; })
|
||||
.then(render)
|
||||
.catch(hide);
|
||||
}, 150);
|
||||
}
|
||||
|
||||
input.addEventListener('focus', load);
|
||||
input.addEventListener('input', load);
|
||||
input.addEventListener('blur', function () { setTimeout(hide, 150); });
|
||||
input.addEventListener('keydown', function (event) {
|
||||
if (list.hidden) return;
|
||||
var items = list.querySelectorAll('.ac-item');
|
||||
if (!items.length) return;
|
||||
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
||||
event.preventDefault();
|
||||
active = (active + (event.key === 'ArrowDown' ? 1 : -1) + items.length) % items.length;
|
||||
items.forEach(function (el, i) { el.classList.toggle('active', i === active); });
|
||||
} else if (event.key === 'Enter' && active >= 0) {
|
||||
event.preventDefault();
|
||||
items[active].dispatchEvent(new MouseEvent('mousedown', { bubbles: true }));
|
||||
} else if (event.key === 'Escape') {
|
||||
hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function csSerialize() {
|
||||
|
||||
Reference in New Issue
Block a user