First commit

This commit is contained in:
Juhani Krekelä 2021-11-20 22:36:11 +02:00
commit fa1246b318
1 changed files with 430 additions and 0 deletions

430
lukujärjestäjä.html Normal file
View File

@ -0,0 +1,430 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Lukujärjestäjä 0.1</title>
<style>
.pane {
}
.items-list {
list-style-type: none;
}
.list-element-text {
padding-left: 0.2em;
}
#schedule-table td {
min-width: 10ch;
text-align: center;
border: 1px solid;
}
#unscheduled-lessons-box {
border: 1px solid;
min-height: 1;
}
</style>
</head>
<body lang="fi">
<details class="pane" id="classes" open>
<summary>Luokat</summary>
<ul class="items-list" id="class-list"></ul>
<form id="add-class">
<input id="class-name" type="text">
<input type="submit" value="+">
</form>
</details>
<details class="pane" id="teachers">
<summary>Opettajat</summary>
<ul class="items-list" id="teacher-list"></ul>
<form id="add-teacher">
<input id="teacher-name" type="text">
<input type="submit" value="+">
</form>
</details>
<details class="pane" id="lessons">
<summary>Tunnit</summary>
<ul class="items-list" id="lesson-list"></ul>
<form id="add-lesson">
<label>Tunti
<input id="lesson-name" type="text">
</label>
<label>Luokka
<select id="lesson-class"></select>
</label>
<label>Opettaja
<select id="lesson-teacher"></select>
</label>
<input type="submit" value="+">
</form>
</details>
<details class="pane" id="schedules">
<summary>Lukujärjestykset</summary>
<select id="schedule-select">
<optgroup id="schedule-select-classes" label="Luokat"></optgroup>
<optgroup id="schedule-select-teachers" label="Opettajat"></optgroup>
</select>
<table id="schedule-table"></table>
<div class="dropzone" id="unscheduled-lessons-box">
<ul id="unscheduled-lessons"></ul>
</div>
</details>
<script>
'use strict';
const days = ['ma', 'ti', 'ke', 'to', 'pe'];
const hours = [8, 9, 10, 11, 12, 13, 14, 15];
let classes = [];
let teachers = [];
let lessons = [];
listClasses();
listTeachers();
listLessons();
function replacementElement(id) {
let oldElement = document.getElementById(id);
let newElement = document.createElement(oldElement.nodeName);
newElement.id = oldElement.id;
newElement.classList = oldElement.classList;
newElement.label = oldElement.label;
return newElement;
}
function replaceElement(id, newElement) {
let oldElement = document.getElementById(id);
oldElement.parentElement.replaceChild(newElement, oldElement);
}
function newDeleteButton(deleteFunction) {
let deleteButton = document.createElement('input');
deleteButton.type = 'button';
deleteButton.value = '-';
deleteButton.onclick = deleteFunction;
return deleteButton;
}
function newListElementText(text) {
let element = document.createElement('span');
element.className = 'list-element-text';
element.innerText = text;
return element
}
function newOption(text) {
let option = document.createElement('option');
option.value = text;
option.innerText = text;
return option;
}
document.getElementById('add-class').onsubmit = addClass;
function addClass(event) {
event.preventDefault();
let nameField = document.getElementById('class-name');
let name = nameField.value;
if (name === '') {
return;
}
if (classes.includes(name)) {
alert(`Luokka ${name} on jo listassa`);
return;
}
nameField.value = '';
classes.push(name);
classes.sort();
listClasses();
}
function deleteClass(name) {
classes = classes.filter((i) => i !== name);
listClasses();
}
function listClasses() {
let classList = replacementElement('class-list');
let classSelect = replacementElement('lesson-class');
classSelect.appendChild(document.createElement('option'));
let scheduleClassSelect = replacementElement('schedule-select-classes');
for (let name of classes) {
let listElement = document.createElement('li');
listElement.appendChild(newDeleteButton(function() { deleteClass(name); }));
listElement.appendChild(newListElementText(name));
classList.appendChild(listElement);
classSelect.appendChild(newOption(name));
scheduleClassSelect.appendChild(newOption(name));
}
replaceElement('class-list', classList);
replaceElement('lesson-class', classSelect);
replaceElement('schedule-select-classes', scheduleClassSelect);
}
document.getElementById('add-teacher').onsubmit = addTeacher;
function addTeacher(event) {
event.preventDefault();
let nameField = document.getElementById('teacher-name');
let name = nameField.value;
if (name === '') {
return;
}
if (teachers.includes(name)) {
alert(`Opettaja ${name} on jo listassa`);
return;
}
nameField.value = '';
teachers.push(name);
teachers.sort();
listTeachers();
}
function deleteTeacher(name) {
teachers = teachers.filter((i) => i !== name);
listTeachers();
}
function listTeachers() {
let teacherList = replacementElement('teacher-list');
let teacherSelect = replacementElement('lesson-teacher');
teacherSelect.appendChild(document.createElement('option'));
let scheduleTeacherSelect = replacementElement('schedule-select-teachers');
for (let name of teachers) {
let listElement = document.createElement('li');
listElement.appendChild(newDeleteButton(function() { deleteTeacher(name); }));
listElement.appendChild(newListElementText(name));
teacherList.appendChild(listElement);
teacherSelect.appendChild(newOption(name));
scheduleTeacherSelect.appendChild(newOption(name));
}
replaceElement('teacher-list', teacherList);
replaceElement('lesson-teacher', teacherSelect);
replaceElement('schedule-select-teachers', scheduleTeacherSelect);
}
document.getElementById('add-lesson').onsubmit = addLesson;
function addLesson(event) {
event.preventDefault();
let nameField = document.getElementById('lesson-name');
let name = nameField.value;
let classField = document.getElementById('lesson-class');
let className = classField.value;
let teacherField = document.getElementById('lesson-teacher');
let teacherName = teacherField.value;
if (name === '' && className === '' && teacherName === '') {
return;
}
if (className === '' && teacherName === '') {
alert('Tunti tarvitsee joko luokan, opettajan tai molemmat');
return;
}
nameField.value = '';
classField.value = '';
teacherField.value = '';
lessons.push({name: name, class: className, teacher: teacherName});
lessons.sort(function(a, b) {
if (a.class < b.class) {
return -1;
} else if (a.class > b.class) {
return 1;
} else if (a.teacher < b.teacher) {
return -1;
} else if (a.teacher > b.teacher) {
return 1;
} else if (a.name < b.name) {
return -1;
} else if (a.name > b.name) {
return 1;
} else {
return 0;
}
});
listLessons();
}
function deleteLesson(key) {
lessons = lessons.filter((_, i) => i !== key);
listLessons();
}
function listLessons() {
let lessonList = replacementElement('lesson-list');
for (let key of lessons.keys()) {
let lesson = lessons[key];
let listElement = document.createElement('li');
listElement.appendChild(newDeleteButton(function() { deleteLesson(key); }));
listElement.appendChild(newListElementText(lesson.name));
listElement.appendChild(newListElementText(lesson.class));
listElement.appendChild(newListElementText(lesson.teacher));
lessonList.appendChild(listElement);
}
replaceElement('lesson-list', lessonList);
showSchedule();
}
document.getElementById('schedule-select').onchange = showSchedule;
function showSchedule() {
let filter = document.getElementById('schedule-select').value;
let scheduleLessons = [];
for (let key of lessons.keys()) {
let lesson = lessons[key];
if (lesson.class === filter || lesson.teacher === filter) {
scheduleLessons.push({key: key, lesson: lesson});
}
}
let schedule = {};
for (let day of days) {
let daySchedule = {}
for (let hour of hours) {
daySchedule[hour] = null;
}
schedule[day] = daySchedule;
}
let unscheduledLessons = replacementElement('unscheduled-lessons');
for (let lesson of scheduleLessons) {
if (lesson.lesson.at) {
schedule[lesson.lesson.at.day][lesson.lesson.at.hour] = lesson;
} else {
let listElement = document.createElement('li');
listElement.id = `lesson-${lesson.key}`;
listElement.draggable = true;
listElement.appendChild(newListElementText(lesson.lesson.name));
if (lesson.lesson.class !== filter) {
listElement.appendChild(newListElementText(lesson.lesson.class));
}
if (lesson.lesson.teacher !== filter) {
listElement.appendChild(newListElementText(lesson.lesson.teacher));
}
unscheduledLessons.appendChild(listElement);
}
}
replaceElement('unscheduled-lessons', unscheduledLessons);
let scheduleTable = replacementElement('schedule-table');
let tableHeader = document.createElement('tr');
tableHeader.appendChild(document.createElement('th'));
for (let day of days) {
let header = document.createElement('th');
header.innerText = day;
tableHeader.appendChild(header);
}
scheduleTable.appendChild(tableHeader);
for (let hour of hours) {
let row = document.createElement('tr');
let header = document.createElement('th');
header.innerText = hour;
row.appendChild(header);
for (let day of days) {
let cell = document.createElement('td');
if (schedule[day][hour]) {
cell.id = `lesson-${schedule[day][hour].key}`;
cell.draggable = true;
let lesson = schedule[day][hour].lesson;
let nameField = document.createElement('div');
nameField.class = 'schedule-namefield';
nameField.innerText = lesson.name;
cell.appendChild(nameField);
let otherField = document.createElement('div');
otherField.class = 'schedule-otherfield';
if (lesson.class !== filter) {
otherField.innerText = lesson.class;
} else {
otherField.innerText = lesson.teacher;
}
cell.appendChild(otherField);
} else {
cell.id = `cell-${day}-${hour}`;
cell.className = 'dropzone';
}
row.appendChild(cell);
}
scheduleTable.appendChild(row);
}
replaceElement('schedule-table', scheduleTable);
}
let dragged;
document.addEventListener('dragstart', (event) => {
dragged = event.target;
});
document.addEventListener('dragover', (event) => {
event.preventDefault();
});
document.addEventListener('dragenter', (event) => {
if (event.target.className === 'dropzone') {
event.target.style.backgroundColor = '#ccc';
}
});
document.addEventListener('dragleave', (event) => {
if (event.target.className === 'dropzone') {
event.target.style.backgroundColor = '';
}
});
document.addEventListener('drop', (event) => {
event.preventDefault();
if (event.target.className === 'dropzone') {
event.target.style.backgroundColor = '';
let key = Number.parseInt(dragged.id.split('lesson-')[1]);
let lesson = lessons[key];
if (event.target.id === 'unscheduled-lessons-box') {
lesson.at = null;
} else {
let cell = event.target.id.split('cell-')[1];
let day = cell.split('-')[0];
let hour = Number.parseInt(cell.split('-')[1]);
for (let otherLesson of lessons) {
if (!otherLesson.at || otherLesson.at.day !== day || otherLesson.at.hour !== hour) {
continue;
}
if (otherLesson.teacher && otherLesson.teacher === lesson.teacher) {
alert(`Päällekäisyys: ${otherLesson.name} ${otherLesson.class}`);
return;
}
if (otherLesson.class && otherLesson.class === lesson.class) {
alert(`Päällekäisyys: ${otherLesson.name} ${otherLesson.teacher}`);
return;
}
}
lesson.at = {day: day, hour: hour};
}
showSchedule();
}
});
</script>
</body>
</html>