Toteuta opettajat

This commit is contained in:
Juhani Krekelä 2023-08-07 18:51:11 +03:00
parent db99ada4dd
commit 80f235ad57
4 changed files with 200 additions and 2 deletions

View File

@ -40,6 +40,9 @@
margin: 0 0.5em; margin: 0 0.5em;
display: inline; display: inline;
} }
#opettajat > li > span {
margin-left: 0.5em;
}
.piilotettu { .piilotettu {
display: none; display: none;
} }
@ -49,7 +52,7 @@
<input id="kumoa" type="button" value="Kumoa"> <input id="kumoa" type="button" value="Kumoa">
<input id="tee-uudelleen" type="button" value="Tee uudelleen"> <input id="tee-uudelleen" type="button" value="Tee uudelleen">
<details class="ruutu" id="luokat" open> <details class="ruutu" open>
<summary>Luokat</summary> <summary>Luokat</summary>
<div> <div>
<input id="lisää-luokka-aste" type="button" value="+ Aste"> <input id="lisää-luokka-aste" type="button" value="+ Aste">
@ -57,6 +60,21 @@
</div> </div>
</details> </details>
<details class="ruutu" open>
<summary>Opettajat</summary>
<div>
<form id="lisää-opettaja">
<span class="virhe piilotettu" id="opettaja-virhe">virhe</span>
<label for="opettaja-nimi">Nimi</label>
<input id="opettaja-nimi" type="text" required>
<label for="opettaja-lyhenne">Lyhenne</label>
<input id="opettaja-lyhenne" type="text">
<input type="submit" value="+">
</form>
<ul id="opettajat"></ul>
</div>
</details>
<script src="testit.js"></script> <script src="testit.js"></script>
<script src="tietotyypit.js"></script> <script src="tietotyypit.js"></script>
<script src="tietomalli.js"></script> <script src="tietomalli.js"></script>

View File

@ -13,8 +13,52 @@ document.getElementById('lisää-luokka-aste').addEventListener('click', () => {
piirräLuokat(); piirräLuokat();
}); });
document.getElementById('lisää-opettaja').addEventListener('submit', (tapahtuma) => {
tapahtuma.preventDefault();
let virheElementti = document.getElementById('opettaja-virhe');
let nimiElementti = document.getElementById('opettaja-nimi');
let lyhenneElementti = document.getElementById('opettaja-lyhenne');
let nimi = nimiElementti.value;
let lyhenne = lyhenneElementti.value;
// Jos käyttäjä ei ole manuallisesti lisännyt lyhennettä, käytä
// automaattisesti luotua.
if (lyhenne === '') {
lyhenne = lyhenneElementti.placeholder;
}
if (opettajat.lyhenne(lyhenne) === undefined) {
suorita(tapahtumaTyypit.lisääOpettaja, lyhenne, nimi);
nimiElementti.value = '';
lyhenneElementti.value = '';
lyhenneElementti.placeholder = '';
virheElementti.classList.add('piilotettu');
piirräOpettajat();
} else {
virheElementti.firstChild.textContent =
`Jokaisella opettajalla tulee olla oma lyhenne. Lyhenne ${lyhenne} on jo käytössä opettajalla ${nimi}`;
virheElementti.classList.remove('piilotettu');
}
});
document.getElementById('opettaja-nimi').addEventListener('input', () => {
let osat = document.getElementById('opettaja-nimi').value.split(' ');
let lyhenne = [];
for (let osa of osat) {
if (osa.length !== 0) {
// TODO: Toimii vain yhden koodipisteen pituisilla
// grafeemiklustereilla.
let koodi = osa.codePointAt(0);
lyhenne.push(String.fromCodePoint(koodi));
}
}
lyhenne = lyhenne.join('');
document.getElementById('opettaja-lyhenne').placeholder = lyhenne;
});
function piirräKaikki() { function piirräKaikki() {
piirräLuokat(); piirräLuokat();
piirräOpettajat();
} }
function piirräLuokat() { function piirräLuokat() {
@ -115,6 +159,41 @@ function luoLuokkaLista(aste) {
return luokkaLista; return luokkaLista;
} }
function piirräOpettajat() {
let vanhaOpettajaLista = document.getElementById('opettajat');
let opettajaLista = luoOpettajaLista();
vanhaOpettajaLista.parentNode.replaceChild(
opettajaLista,
vanhaOpettajaLista
);
}
function luoOpettajaLista() {
let opettajaLista = document.createElement('ul');
opettajaLista.id = 'opettajat';
for (let [lyhenne, nimi] of opettajat.opettajat()) {
opettajaLista.appendChild(luoOpettajaListassa(lyhenne, nimi));
}
return opettajaLista;
}
function luoOpettajaListassa(lyhenne, nimi) {
let opettajaListassa = document.createElement('li');
opettajaListassa.appendChild(luoPainike('-', () => {
suorita(tapahtumaTyypit.poistaOpettaja, lyhenne);
piirräOpettajat();
}));
let opettajanNimi = document.createElement('span');
opettajanNimi.appendChild(document.createTextNode(`${lyhenne} ${nimi}`));
opettajaListassa.appendChild(opettajanNimi);
return opettajaListassa;
}
function luoPainike(teksti, funktio) { function luoPainike(teksti, funktio) {
let painike = document.createElement('input'); let painike = document.createElement('input');
painike.type = 'button'; painike.type = 'button';

View File

@ -6,6 +6,9 @@ const tapahtumaTyypit = {
lisääLuokka: 'lisääLuokka', lisääLuokka: 'lisääLuokka',
poistaLuokka: 'poistaLuokka', poistaLuokka: 'poistaLuokka',
lisääOpettaja: 'lisääOpettaja',
poistaOpettaja: 'poistaOpettaja',
}; };
class Tapahtuma { class Tapahtuma {
@ -16,13 +19,14 @@ class Tapahtuma {
} }
let historia, tulevaisuus; let historia, tulevaisuus;
let luokkaAsteet; let luokkaAsteet, opettajat;
alustaMalli(); alustaMalli();
function alustaMalli() { function alustaMalli() {
historia = []; historia = [];
tulevaisuus = []; tulevaisuus = [];
luokkaAsteet = new LuokkaAsteet(); luokkaAsteet = new LuokkaAsteet();
opettajat = new Opettajat();
} }
function suorita(tyyppi, ...argumentit) { function suorita(tyyppi, ...argumentit) {
@ -40,6 +44,7 @@ function suorita(tyyppi, ...argumentit) {
assertEq('muutaAste argumentit määrä', argumentit.length, 2); assertEq('muutaAste argumentit määrä', argumentit.length, 2);
luokkaAsteet.muuta(...argumentit) luokkaAsteet.muuta(...argumentit)
break; break;
case tapahtumaTyypit.lisääLuokka: case tapahtumaTyypit.lisääLuokka:
assertEq('lisääLuokka argumentit määrä', argumentit.length, 1); assertEq('lisääLuokka argumentit määrä', argumentit.length, 1);
luokkaAsteet.asteet[argumentit[0]].lisää(); luokkaAsteet.asteet[argumentit[0]].lisää();
@ -48,6 +53,16 @@ function suorita(tyyppi, ...argumentit) {
assertEq('poistaLuokka argumentit määrä', argumentit.length, 1); assertEq('poistaLuokka argumentit määrä', argumentit.length, 1);
luokkaAsteet.asteet[argumentit[0]].poista(); luokkaAsteet.asteet[argumentit[0]].poista();
break; break;
case tapahtumaTyypit.lisääOpettaja:
assertEq('lisääOpettaja argumentit määrä', argumentit.length, 2);
opettajat.lisää(argumentit[0], argumentit[1]);
break;
case tapahtumaTyypit.poistaOpettaja:
assertEq('poistaOpettaja argumentit määrä', argumentit.length, 1);
opettajat.poista(argumentit[0]);
break;
default: default:
throw new Error(`tuntematon tapahtumatyyppi ${tyyppi}`); throw new Error(`tuntematon tapahtumatyyppi ${tyyppi}`);
} }
@ -89,10 +104,12 @@ testi('mallin alustaminen', () => {
historia = undefined; historia = undefined;
tulevaisuus = undefined; tulevaisuus = undefined;
luokkaAsteet = undefined; luokkaAsteet = undefined;
opettajat = undefined;
alustaMalli(); alustaMalli();
assertNe('historia', historia, undefined); assertNe('historia', historia, undefined);
assertNe('tulevaisuus', tulevaisuus, undefined); assertNe('tulevaisuus', tulevaisuus, undefined);
assertNe('luokkaAsteet', luokkaAsteet, undefined); assertNe('luokkaAsteet', luokkaAsteet, undefined);
assertNe('opettajat', opettajat, undefined);
}); });
testi('tapahtumahistoria', () => { testi('tapahtumahistoria', () => {
@ -184,3 +201,12 @@ testi('luokkien käsittely', () => {
assertEq('poistettua', luokkaAsteet.asteet[1].luokat(), ['A']); assertEq('poistettua', luokkaAsteet.asteet[1].luokat(), ['A']);
alustaMalli(); alustaMalli();
}); });
testi('opettajien käsittely', () => {
alustaMalli();
assertEq('aluksi', opettajat.opettajat(), []);
suorita(tapahtumaTyypit.lisääOpettaja, 'MM', 'Maija Meikäläinen');
assertEq('lisättyä', opettajat.opettajat(), [['MM', 'Maija Meikäläinen']]);
suorita(tapahtumaTyypit.poistaOpettaja, 'MM');
assertEq('poistettua', opettajat.opettajat(), []);
});

View File

@ -70,6 +70,33 @@ class LuokkaAsteet {
} }
} }
class Opettajat {
#opettajat = new Map();
opettajat() {
let lista = Array.from(this.#opettajat.entries());
lista.sort();
return lista;
}
lyhenne(lyhenne) {
return this.#opettajat.get(lyhenne);
}
lisää(lyhenne, nimi) {
if (this.#opettajat.has(lyhenne)) {
throw new Error(`opettaja on jo olemassa lyhenteellä ${lyhenne}`);
}
this.#opettajat.set(lyhenne, nimi);
}
poista(lyhenne) {
if (!this.#opettajat.delete(lyhenne)) {
throw new Error(`ei opettajaa lyhenteellä ${lyhenne}`);
}
}
}
testi('seuraava aste', () => { testi('seuraava aste', () => {
let luokkaAsteet = new LuokkaAsteet(); let luokkaAsteet = new LuokkaAsteet();
assertEq('aluksi', luokkaAsteet.seuraavaAste(), 1); assertEq('aluksi', luokkaAsteet.seuraavaAste(), 1);
@ -138,3 +165,51 @@ testi('luokkien poistaminen', () => {
}); });
assertEq('poistettua', aste.luokat(), ['A']); assertEq('poistettua', aste.luokat(), ['A']);
}); });
testi('opettajien lisääminen', () => {
let opettajat = new Opettajat();
assertEq('aluksi', opettajat.opettajat(), []);
opettajat.lisää('MM', 'Maija Meikäläinen');
opettajat.lisää('AS', 'Aili Savolainen');
opettajat.lisää('KV', 'Kari Virtanen');
assertThrow('sama lyhenne', 'opettaja on jo olemassa lyhenteellä MM', () => {
opettajat.lisää('MM', 'Matti Meikäläinen');
});
opettajat.lisää('MaM', 'Matti Meikäläinen');
assertEq('lisättyä', opettajat.opettajat(), [
['AS', 'Aili Savolainen'],
['KV', 'Kari Virtanen'],
['MM', 'Maija Meikäläinen'],
['MaM', 'Matti Meikäläinen'],
]);
});
testi('opettajien poistaminen', () => {
let opettajat = new Opettajat();
opettajat.lisää('MM', 'Maija Meikäläinen');
opettajat.lisää('AS', 'Aili Savolainen');
opettajat.lisää('KV', 'Kari Virtanen');
opettajat.lisää('MaM', 'Matti Meikäläinen');
opettajat.poista('MM');
assertThrow('jo poistettu', 'ei opettajaa lyhenteellä MM', () => {
opettajat.poista('MM');
});
assertEq('poistettua', opettajat.opettajat(), [
['AS', 'Aili Savolainen'],
['KV', 'Kari Virtanen'],
['MaM', 'Matti Meikäläinen'],
]);
});
testi('opettajien lyhenteen', () => {
let opettajat = new Opettajat();
opettajat.lisää('MM', 'Maija Meikäläinen');
opettajat.lisää('AS', 'Aili Savolainen');
opettajat.lisää('KV', 'Kari Virtanen');
opettajat.lisää('MaM', 'Matti Meikäläinen');
assertEq('MM', opettajat.lyhenne('MM'), 'Maija Meikäläinen');
assertEq('AS', opettajat.lyhenne('AS'), 'Aili Savolainen');
assertEq('KV', opettajat.lyhenne('KV'), 'Kari Virtanen');
assertEq('MaM', opettajat.lyhenne('MaM'), 'Matti Meikäläinen');
assertEq('ZZ', opettajat.lyhenne('ZZ'), undefined);
});