add autocomplete input for student selection in journal filters, link creation, and links admin

This commit is contained in:
dev
2026-09-05 20:26:21 +03:00
parent ee0a18e4cd
commit 7a72cb4547
5 changed files with 66 additions and 22 deletions
+25 -9
View File
@@ -13,7 +13,7 @@
<h2>Журнал</h2>
<div class="filters">
<div><label>Поиск</label><input type="text" id="searchInput" class="search-input" placeholder="Имя или описание"></div>
<div><label>Студент</label><select id="studentFilter"><option value="">Все</option></select></div>
<div><label>Студент</label><input type="text" id="studentFilter" list="studentFilterList" placeholder="Все / введите имя..."><datalist id="studentFilterList"></datalist></div>
<div><label>Группа</label><select id="groupFilter"><option value="">Все группы</option></select></div>
<div><label>С</label><input type="date" id="dateFrom"></div>
<div><label>По</label><input type="date" id="dateTo"></div>
@@ -67,6 +67,14 @@
<label>Название ссылки</label>
<input type="text" id="linkNameInput">
</div>
<div>
<label>Группа (если выбрана)</label>
<input type="text" id="linkGroupPreview" readonly style="background:var(--bg);color:var(--muted);cursor:not-allowed">
</div>
<div>
<label>Ученик (необязательно)</label>
<input type="text" id="linkStudent" list="linkStudentList" placeholder="Все / введите имя..."><datalist id="linkStudentList"></datalist>
</div>
<div class="actions">
<button class="cancel" onclick="closeLinkCreate()">Отмена</button>
<button class="save" onclick="createLink()">Создать</button>
@@ -184,15 +192,10 @@ async function loadGroupOptions() {
async function loadStudentOptions() {
if (studentsLoaded) return;
const sel = document.getElementById('studentFilter');
while (sel.options.length > 1) sel.remove(1);
const dl = document.getElementById('studentFilterList');
const res = await fetch(`${API}/api/students/names`, { headers: hdr() });
const names = await res.json();
names.forEach(n => {
const o = document.createElement('option');
o.value = n; o.textContent = n;
sel.appendChild(o);
});
dl.innerHTML = names.map(n => `<option value="${esc(n)}">`).join('');
studentsLoaded = true;
}
@@ -330,6 +333,7 @@ async function exportCSV() {
// --- Ссылки ---
let linkGroups = [];
let linkStudentsLoaded = false;
let createdLinkUrl = '';
function fmtD(d) { return d ? d.split('-').reverse().join('.') : 'весь период'; }
@@ -343,11 +347,22 @@ async function openLinkCreate() {
const res = await fetch(`${API}/api/groups`, { headers: hdr() });
linkGroups = await res.json();
}
if (!linkStudentsLoaded) {
const res = await fetch(`${API}/api/students/names`, { headers: hdr() });
const names = await res.json();
const dl = document.getElementById('linkStudentList');
dl.innerHTML = names.map(n => `<option value="${esc(n)}">`).join('');
linkStudentsLoaded = true;
}
// Capture current student filter
const currentStudent = document.getElementById('studentFilter').value;
const g = linkGroups.find(x => String(x.id) === String(gid));
document.getElementById('linkPreview').innerHTML =
`Будут показаны записи: <b>${esc(g ? g.name : '')}</b><br>Период: <b>${fmtD(df)}</b> — <b>${fmtD(dt)}</b>`;
document.getElementById('linkGroupPreview').value = g ? g.name : '';
const dfl = df.split('-').reverse().join('.');
document.getElementById('linkNameInput').value = `${g ? g.name : ''} ${dfl}`;
document.getElementById('linkStudent').value = currentStudent;
document.getElementById('linkCreateView').style.display = '';
document.getElementById('linkResultView').style.display = 'none';
document.getElementById('linkModal').classList.add('open');
@@ -360,13 +375,14 @@ function closeLinkCreate() {
async function createLink() {
const name = document.getElementById('linkNameInput').value.trim();
const group_id = document.getElementById('groupFilter').value;
const student_name = document.getElementById('linkStudent').value;
const date_from = document.getElementById('dateFrom').value;
const date_to = document.getElementById('dateTo').value;
if (!name) { alert('Введите название'); return; }
const res = await fetch(`${API}/api/links`, {
method: 'POST',
headers: hdrJson(),
body: JSON.stringify({ name, group_id, date_from: date_from || null, date_to: date_to || null })
body: JSON.stringify({ name, group_id, student_name: student_name || null, date_from: date_from || null, date_to: date_to || null })
});
if (!res.ok) { const err = await res.json(); alert(err.error || 'Ошибка'); return; }
const link = await res.json();