Napište program, který zjistí, jestli je zadané rodné číslo platné. (Skutečná rodná čísla mají 9 nebo 10 číslic, my budeme uvažovat pouze rodná čísla mladších lidí, která mají 10 číslic.) Postupujte dle následujících kroků.
-
Založte si projekt příkazem
npm init kodim-app@latest cviceni-rodna-cisla html-css-js
Ve VS Code otevřete složku
cviceni-rodna-cisla
. -
Pomocí funkce
prompt
se zeptejte uživatele na rodné číslo. Rodné číslo zkontrolujte podle bodů popsaných níže. -
Každé rodné číslo musí mít přesně 10 znaků. Zkontrolujte tedy, že zadaný řetězec je délky 10 a neprojdou nám například vstupy typu
nepovím
Slovo „nepovím“ má totiž jen 7 znaků.
123456789123456789
Řetězec „123456789123456789“ má totiž 18 znaků.
Pokud uživatel zadal číslo špatné délky, vypište do stránky text:
❌ Uživatel zadal rodné číslo neplatné délky.
V opačném případě vypište:
✔️ Zadané rodné číslo má správně deset znaků.
-
Každé rodné číslo musí být celé číslo. Zda je nějaká hodnota celé číslo, v JavaScriptu zkontrolujete pomocí funkce
Number.isInteger
. Musíte však vstup předtím převést na číslo pomocí funkceNumber
.Number.isInteger(Number('25')); // vrací true Number.isInteger(Number('25.16')); // vrací false Number.isInteger(Number('ahoj')); // vrací false
Opět vypište do stránky, zda podmínka platí.
✔️ Rodné číslo je celé číslo.
❌ Rodné číslo obsahuje nepovolené znaky.
-
Každé rodné číslo musí být dělitelné 11. Zkontrolujte tedy, že zadané číslo je dělitelné jedenácti, a výsledek opět vypište do stránky.
✔️ Rodné číslo je dělitelné 11.
❌ Rodné číslo není dělitelné číslem 11.
- Pokud jsou všechny podmínky splněny, rodné číslo budeme považovat za platné. Informaci o platnosti vypište do stránky.
✔️ Zadané rodné číslo je platné.
❌ Uživatel zadal neplatné rodné číslo.
Po zadání rodného čísla by se na stránce měly objevit čtyři výpisy.
Řešení
const rodneCislo = prompt('Jaké je tvé rodné číslo?');
let platne = true;
if (rodneCislo.length === 10) {
document.body.innerHTML += '✔️ Zadané rodné číslo má správně deset znaků.<br>';
} else {
document.body.innerHTML += '❌ Uživatel zadal rodné číslo neplatné délky.<br>';
platne = false;
}
if (Number.isInteger(Number(rodneCislo))) {
document.body.innerHTML += '✔️ Rodné číslo je celé číslo.<br>';
} else {
document.body.innerHTML += '❌ Rodné číslo obsahuje nepovolené znaky.<br>';
platne = false;
}
if (Number(rodneCislo) % 11 === 0) {
document.body.innerHTML += '✔️ Rodné číslo je dělitelné 11.<br>';
} else {
document.body.innerHTML += '❌ Rodné číslo není dělitelné číslem 11.<br>';
platne = false;
}
if (platne) {
document.body.innerHTML += '✔️ Zadané rodné číslo je platné.<br>';
} else {
document.body.innerHTML += '❌ Uživatel zadal neplatné rodné číslo.<br>';
}
Přepiště kód z předchozího příkladu do funkce s názvem checkBirthID
, která zkontroluje platnost rodného čísla. Funkce bude mít jeden parametr, ve kterém bude očekávat rodné číslo jako řetězec. Funkce bude vracet řetězec s výsledkem kontroly podle následujících pravidel:
'invalidLength'
v případě, že vstup nemá 10 znaků,'notANumber'
v případě, že vstup není číslo,'failedChecksum'
v případě, že číslo není dělitalné 11,'ok'
v případě, že číslo prošlo kontrolou.
Funkci otestujte třeba na hodnotách:
const rodnaCislaKOtestovani = [
'123',
'nepovím',
'7060201236',
'7060201235',
'123456789123456789',
'9062185440',
'123č56q8y7',
];
Řešení
const checkBirthID = (rodneCislo) => {
if (rodneCislo.length !== 10) {
return 'invalidLength';
}
if (!Number.isInteger(Number(rodneCislo))) {
return 'notANumber';
}
if (Number(rodneCislo) % 11 !== 0) {
return 'failedChecksum';
}
return 'ok';
};
const rodnaCislaKOtestovani = [
'123',
'nepovím',
'7060201236',
'123456789123456789',
'9062185440',
'123č56q8y7',
];
rodnaCislaKOtestovani.forEach((rc) => {
document.body.innerHTML += `Rodné číslo <code>${rc}</code> `;
const vysledek = checkBirthID(rc);
if (vysledek === 'ok') {
document.body.innerHTML += 'je platné. ✔️<br>';
} else {
document.body.innerHTML += `není neplatné. Důvod: ${vysledek}. ❌<br>`;
}
});
V případě, že uživatel zadal do rodného čísla špatné znaky, budeme chtít tyto znaky vypsat a ukázat, kde se stala chyba. Pokračuje v kódu z předchozího příkladu.
- Vytvořte pole
digits
obsahující všechny cifry'0'
až'9'
jako řetězce. - Napište funkci
isDigit
, která na vstupu dostane řetězec a vrátítrue
, pokud tento řetězec obsahuje právě jednu cifru. Použijte k tomu poledigits
a metoduincludes
(viz dokumentace). V opačném případě funkce vrátífalse
. - Napište funci
logInvalidCharacters
. Funkce na vstupu dostane řetězec, ten převede na pole znaků (zkuste vygooglit, jak na to). Následně všechny znaky projde pomocíforEach
. Do konzole vypíše ty znaky, které nesplňují podmínky z funkceisDigit
.logInvalidCharacters
vyzkoušejte například na textu'123č56q8y7'
a'7060201236'
. V prvním případě by se v konzoli mělo objevit na třech řádcíchč
,q
ay
. Pro druhý text by se nemělo vypsat nic.
Řešení
const digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
const isDigit = (znak) => znak.length === 1 && digits.includes(znak);
const logInvalidCharacters = (vstup) => {
Array.from(vstup).forEach((znak) => {
if (!isDigit(znak)) {
document.body.innerHTML += `Vstup obsahuje neplatný znak „${znak}“.<br>`;
}
});
};
const checkBirthID = (rodneCislo) => {
if (rodneCislo.length !== 10) {
return 'invalidLength';
}
if (!Number.isInteger(Number(rodneCislo))) {
return 'notANumber';
}
if (Number(rodneCislo) % 11 !== 0) {
return 'failedChecksum';
}
return 'ok';
};
const rodnaCislaKOtestovani = [
'123',
'nepovím',
'7060201236',
'123456789123456789',
'9062185440',
'123č56q8y7',
];
rodnaCislaKOtestovani.forEach((rc) => {
document.body.innerHTML + `Rodné číslo <code>${rc}</code> `;
const vysledek = checkBirthID(rc);
if (vysledek === 'ok') {
document.body.innerHTML += 'je platné. ✔️<br>';
} else {
document.body.innerHTML += `je neplatné. Důvod: ${vysledek}. ❌<br>`;
if (vysledek === 'notANumber') {
logInvalidCharacters(rc);
}
}
});
V předchozím cvičení jsme pomocí cyklu vypisovali všechny špatně zadané znaky do konzole. Nyní tento kód přepíšeme tak, aby místo výpisů do konzole vyrobil pole objektů, obsahující informace o každém znaku. Například pro vstup 462748/312
chceme jako výsledek obdržet takovéto pole.
[
{ char: '4', digit: true },
{ char: '6', digit: true },
{ char: '2', digit: true },
{ char: '7', digit: true },
{ char: '4', digit: true },
{ char: '8', digit: true },
{ char: '/', digit: false },
{ char: '3', digit: true },
{ char: '1', digit: true },
{ char: '2', digit: true },
];
Napište tedy funkci validateCharacters
, která na vstupu dostane text a vrátí pole ve formátu jako výše. Postupujte následovně:
-
Na začátku funkce si vytvořte proměnnou
result
, do které uložte prázdné pole. -
Projděte vstup znak po znaku jako v předchozim cvičení. Místo výpisu do stránky však pro každý znak vyrobte odpovídající objekt a vložte jej do pole
result
pomocí metodypush
. -
Na konci funkce pole
result
vraťte pomocíreturn
. -
Vyzkoušejte vaši funci zavolat třeba se vstupy
'123č56q8y7'
a'7060201236'
a výsledná pole vypište pro otestování do konzole (pomocíconsole.log
).> validateCharacters('123č56q8y7') [ { char: '1', digit: true }, { char: '2', digit: true }, { char: '3', digit: true }, { char: 'č', digit: false }, { char: '5', digit: true }, { char: '6', digit: true }, { char: 'q', digit: false }, { char: '8', digit: true }, { char: 'y', digit: false }, { char: '7', digit: true }, ]; > validateCharacters('7060201236') [ { char: '7', digit: true }, { char: '0', digit: true }, { char: '6', digit: true }, { char: '0', digit: true }, { char: '2', digit: true }, { char: '0', digit: true }, { char: '1', digit: true }, { char: '2', digit: true }, { char: '3', digit: true }, { char: '6', digit: true }, ];
Řešení
const validateCharacters = (vstup) => {
const result = [];
Array.from(vstup).forEach((znak) => {
result.push({ char: znak, digit: isDigit(znak) });
});
return result;
};
Upravte vaši aplikaci na kontrolu rodných čísel tak, aby obsahovala formulář.
- Do HTML vaší stránky vložte formulář s textovým políčkem pro rodné číslo. Formulář se bude odesílat tlačítkem Zkontrolovat.
- Na událost
submit
formuláře pověste posluchač, který provede kontrolu zadaného rodného čísla tak, jak jsme ji dělali v předchozích cvičeních. - Do HTML vložte pod formulář
div
s nějakým vhodně zvolenýmid
. Tentodiv
bude představovat zprávu pro uživatele. - Z přechozích cvičení máme hotovou funkci
checkBirthID
, Pokud pro uživatelův vstup vrátí'ok'
, vypište do vašehodiv
u
✔️ V pořádku.
- Pokud vrátí cokoliv jiného, vypište zprávu ve smyslu
❌ V rodném čísle jsou chyby.
- Vyzkoušejte do formuláře vyplnit aspoň jedno platné rodné číslo a jedno neplatné.
Řešení
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Opakování JavaScriptu</title>
<script type="module" src="index.js"></script>
</head>
<body>
<form id="formular">
<label>Rodné číslo: <input /></label>
<button>Zkontrolovat</button>
</form>
<div id="vystup"></div>
</body>
</html>
// … zde jsou validační funkce z předchozích cvičení …
const formular = document.querySelector('#formular');
formular.addEventListener('submit', (event) => {
event.preventDefault();
const vstup = formular.querySelector('input').value;
const vystupElm = document.querySelector('#vystup');
if (checkBirthID(vstup) === 'ok') {
vystupElm.textContent = '✔️ V pořádku.';
} else {
vystupElm.textContent = '❌ V rodném čísle jsou chyby.';
}
});
Pokračuje v kódu předchozího příkladu. Budeme chtít zobrazit jednotlivé cifry rodného čísla dle následujícího vzoru.
Cifry budeme do stránky vkládat pomocí vlastnosti innerHTML
.
- Nedříve si rozmysleme, jak bude vypadat HTML pro jednu cifru. Může jít například o jednoduchý
div
s nějakou vhodně nastylovanou třídou. - Pokud je znak platná číslice, bude mít na stránce zelené pozadí
#00DD00
. V opačném případě bude mít červené pozadí#FF8686
. - V souboru
index.html
vytvořtediv
s nějakým smysluplnýmid
, ve kterém budeme zobrazovat jednotlivé cifry. Nastylujte jej pomocí flexboxu tak, abychom mohli cifry zobrazovat vedle sebe. - Jakmile uživatel klikne na tlačítko Zkontrolovat, zavolejte pro uživatelův vstup funkci
validateCharacters
. Projděte vrácené pole pomocí cykluforEach
a naplňte váš připravenýdiv
ciframi s použitím vlastnostiinnerHTML
.
Vaše aplikce by měla ve výsledku fungovat tak, že kdykoliv uživatel zadá rodné číslo a nechá si jej zkontrolovat, aplikace vypíše, zda je číslo zadané dobře nebo špatně, a zobrazí jednotlivé znaky čísla s tím, že cifry jsou zelené a špatně zadané znaky jsou červené.
Řešení
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Opakování JavaScriptu</title>
<script type="module" src="index.js"></script>
</head>
<body>
<form id="formular">
<label>Rodné číslo: <input /></label>
<button>Zkontrolovat</button>
</form>
<div id="vystup"></div>
<div id="cifry"></div>
</body>
</html>
const formular = document.querySelector('#formular');
formular.addEventListener('submit', (event) => {
event.preventDefault();
const vstup = formular.querySelector('input').value;
const vystupElm = document.querySelector('#vystup');
const vysledekValidace = checkBirthID(vstup);
if (vysledekValidace === 'ok') {
vystupElm.textContent = '✔️ V pořádku.';
} else {
vystupElm.textContent = '❌ V rodném čísle jsou chyby.';
}
const overeni = validateCharacters(vstup);
const cifry = document.querySelector('#cifry');
overeni.forEach((znak) => {
cifry.innerHTML += `
<span style="background-color: ${znak.digit ? '#00DD00' : '#FF8686'}">
${znak.char}
</span>
`;
});
});