First commit
This commit is contained in:
commit
fa1246b318
1 changed files with 430 additions and 0 deletions
430
lukujärjestäjä.html
Normal file
430
lukujärjestäjä.html
Normal 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>
|
Loading…
Reference in a new issue