Browse Source

add AI material navíc, README popisky všude

master
skrabanek 7 days ago
parent
commit
22ec18730f
  1. 1
      .gitignore
  2. 40
      01_uvod/README.md
  3. 124
      02/README.md
  4. 53
      03_css_uvod/README.md
  5. 45
      04_layout/README.md
  6. 71
      05_js_intro/README.md
  7. 62
      06_js_html/README.md
  8. 85
      07_js_css_dom/README.md
  9. 94
      08_js_form/README.md
  10. 100
      09_mediaquerry/README.md
  11. 129
      10_flex/README.md
  12. 117
      11_json/README.md
  13. 150
      12_grid/README.md
  14. 119
      13_boostrap_intro/README.md
  15. 162
      14_bootstrap_layout/README.md
  16. 165
      15_bootstrap_components/README.md
  17. 171
      16_carousel/README.md
  18. 224
      17_modal/README.md
  19. 181
      18_forms/README.md
  20. 220
      19_todolist/README.md
  21. 228
      20_ajax/README.md
  22. 248
      AI_extra_material/18_form_validation_bootstrap/ZADANI.md
  23. 12048
      AI_extra_material/18_form_validation_bootstrap/css/bootstrap.css
  24. 6
      AI_extra_material/18_form_validation_bootstrap/css/bootstrap.min.css
  25. 429
      AI_extra_material/18_form_validation_bootstrap/index.html
  26. 6312
      AI_extra_material/18_form_validation_bootstrap/js/bootstrap.bundle.js
  27. 7
      AI_extra_material/18_form_validation_bootstrap/js/bootstrap.bundle.min.js
  28. 280
      AI_extra_material/18_form_validation_bootstrap/reseni_kontaktni_formular.html
  29. 128
      AI_extra_material/18_form_validation_bootstrap/template.html
  30. 208
      AI_extra_material/18a_form_xss_demo/RYCHLY_NAVOD.md
  31. 377
      AI_extra_material/18a_form_xss_demo/ZADANI.md
  32. 157
      AI_extra_material/18a_form_xss_demo/bezpecna_jednoducha.html
  33. 335
      AI_extra_material/18a_form_xss_demo/bezpecna_verze.html
  34. 12048
      AI_extra_material/18a_form_xss_demo/css/bootstrap.css
  35. 6
      AI_extra_material/18a_form_xss_demo/css/bootstrap.min.css
  36. 313
      AI_extra_material/18a_form_xss_demo/index.html
  37. 6312
      AI_extra_material/18a_form_xss_demo/js/bootstrap.bundle.js
  38. 7
      AI_extra_material/18a_form_xss_demo/js/bootstrap.bundle.min.js
  39. 154
      AI_extra_material/18a_form_xss_demo/zranitelna_jednoducha.html
  40. 273
      AI_extra_material/18a_form_xss_demo/zranitelna_verze.html
  41. 249
      AI_extra_material/AI_PROJEKTY_README.md
  42. 21
      AI_extra_material/ISP_PRG_pliva_1I.txt
  43. 428
      AI_extra_material/ISP_WTL_3I.md
  44. 31
      AI_extra_material/ISP_WTL_3I.txt
  45. 101
      AI_extra_material/README.md
  46. 351
      AI_extra_material/UCITEL_INFO.md
  47. 158
      AI_extra_material/ai_01_grid_responsive/README.md
  48. 49
      AI_extra_material/ai_01_grid_responsive/ZADANI.md
  49. 18
      AI_extra_material/ai_01_grid_responsive/index.html
  50. 151
      AI_extra_material/ai_01_grid_responsive/reseni.css
  51. 51
      AI_extra_material/ai_01_grid_responsive/reseni.html
  52. 50
      AI_extra_material/ai_01_grid_responsive/style.css
  53. 221
      AI_extra_material/ai_02_semantic_portfolio/README.md
  54. 67
      AI_extra_material/ai_02_semantic_portfolio/ZADANI.md
  55. 36
      AI_extra_material/ai_02_semantic_portfolio/index.html
  56. 422
      AI_extra_material/ai_02_semantic_portfolio/reseni.css
  57. 119
      AI_extra_material/ai_02_semantic_portfolio/reseni.html
  58. 54
      AI_extra_material/ai_02_semantic_portfolio/style.css
  59. 301
      AI_extra_material/ai_03_form_validation/README.md
  60. 93
      AI_extra_material/ai_03_form_validation/ZADANI.md
  61. 50
      AI_extra_material/ai_03_form_validation/index.html
  62. 256
      AI_extra_material/ai_03_form_validation/reseni.css
  63. 76
      AI_extra_material/ai_03_form_validation/reseni.html
  64. 376
      AI_extra_material/ai_03_form_validation/reseni.js
  65. 96
      AI_extra_material/ai_03_form_validation/script.js
  66. 59
      AI_extra_material/ai_03_form_validation/style.css
  67. 377
      AI_extra_material/ai_04_prep_bootstrap/README.md
  68. 173
      AI_extra_material/ai_04_prep_bootstrap/RESENI_PRIKLAD.md
  69. 166
      AI_extra_material/ai_04_prep_bootstrap/ZADANI.md
  70. 42
      AI_extra_material/ai_04_prep_bootstrap/css/animations.css
  71. 131
      AI_extra_material/ai_04_prep_bootstrap/css/style.css
  72. 61
      AI_extra_material/ai_04_prep_bootstrap/index.html
  73. 37
      AI_extra_material/ai_04_prep_bootstrap/js/main.js
  74. 36
      AI_extra_material/ai_04_prep_bootstrap/js/scroll.js
  75. 48
      AI_extra_material/ai_04_prep_bootstrap/js/validation.js
  76. 129
      README.md
  77. 177
      novyprojekt_bootstrap/README.md

1
.gitignore

@ -10,5 +10,4 @@
.history/ .history/
CLAUDE.md CLAUDE.md
AI/*
.claude/ .claude/

40
01_uvod/README.md

@ -0,0 +1,40 @@
# 01 - Úvod do HTML
## 🎯 Co se naučíte
V této lekci se seznámíte se základy HTML a strukturou webové stránky.
## 📚 Témata lekce
- **Základní struktura HTML dokumentu** (`<!DOCTYPE html>`, `<html>`, `<head>`, `<body>`)
- **Nadpisy** (`<h1>` až `<h6>`)
- **Odstavce** (`<p>`)
- **Odkazy** (`<a href="">`)
- **Obrázky** (`<img src="" alt="">`)
- **Komentáře v HTML** (`<!-- komentář -->`)
- **Zalomení řádku** (`<br>`)
## 📂 Soubory v projektu
- `index.html` - hlavní HTML soubor s ukázkami základních HTML tagů
- `about.html` - další stránka pro demonstraci odkazů
- `profily/` - složka s příklady vnořené struktury souborů
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči (dvojklik nebo přes Live Server)
2. Prohlédněte si HTML kód v editoru
3. Zkuste upravit texty, přidat nové nadpisy nebo odstavce
4. Vyzkoušejte vytvořit vlastní odkazy na nové stránky
## 💡 Tip pro studenty
- Používejte komentáře (`<!-- -->`) pro poznámky v kódu
- Zkratka pro zakomentování: `CTRL+K CTRL+C` (odkomentování: `CTRL+K CTRL+U`)
- Každý tag, který otevřete, musíte i zavřít (např. `<p>...</p>`)
- Atribut `alt` u obrázků je povinný (popisuje obrázek)
## 🔗 Související lekce
- **Další:** 02 - pokračování v HTML
- **Související:** 03_css_uvod - stylování HTML elementů

124
02/README.md

@ -0,0 +1,124 @@
# 02 - HTML Pokročilé Elementy
## 🎯 Co se naučíte
V této lekci se naučíte pracovat s pokročilejšími HTML elementy a Emmet zkratkami.
## 📚 Témata lekce
- **Tabulky** (`<table>`, `<tr>`, `<td>`, `<th>`)
- Struktura tabulek
- Řádky (`<tr>`) a buňky (`<td>`)
- Nadpisy tabulek (`<th>`)
- Stylování pomocí inline CSS
- **Seznamy** (`<ul>`, `<ol>`, `<dl>`)
- Nečíslované seznamy (`<ul>`)
- Číslované seznamy (`<ol>`)
- Definiční seznamy (`<dl>`, `<dt>`, `<dd>`)
- **Emmet zkratky** - rychlé psaní HTML
- **ALT + klikání** - multi-cursor editing
## 📂 Soubory v projektu
- `index.html` - hlavní soubor s ukázkami
- `formular.html` - příklad formuláře
## 💻 Ukázky z lekce
### Tabulka:
```html
<table style="border: 2px black solid;">
<tr>
<th>Jméno</th>
<th>Částka</th>
<th>Měna</th>
</tr>
<tr>
<td>Martin</td>
<td>50</td>
<td>$</td>
</tr>
</table>
```
### Seznamy:
```html
<!-- Nečíslovaný seznam -->
<ul>
<li>První položka</li>
<li>Druhá položka</li>
</ul>
<!-- Číslovaný seznam -->
<ol>
<li>První krok</li>
<li>Druhý krok</li>
</ol>
<!-- Definiční seznam -->
<dl>
<dt>HTML</dt>
<dd>- HyperText Markup Language</dd>
<dt>CSS</dt>
<dd>- Cascading Style Sheets</dd>
</dl>
```
### Emmet zkratky:
```
ul>li*5>a → vytvoří <ul> s 5 <li>, každý obsahuje <a>
table>tr*3>td*4 → vytvoří tabulku 3 řádky × 4 sloupce
p>a → vytvoří <p> s <a> uvnitř
html:5 nebo ! → vytvoří HTML5 šablonu
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Prohlédněte si ukázky tabulek a seznamů
3. Zkuste vytvořit vlastní tabulku s více řádky a sloupci
4. Vyzkoušejte Emmet zkratky v editoru
5. Použijte **ALT + klikání** pro psaní na více místech najednou
## 💡 Tip pro studenty
### Struktura tabulky:
```
<table> ← kontejner tabulky
<tr> ← řádek (Table Row)
<th> ← hlavička (Table Header)
<td> ← buňka (Table Data)
```
### Emmet zkratky - příklady:
- **`html:5`** nebo **`!`** - vytvoří HTML5 šablonu
- **`ul>li*5`** - vytvoří `<ul>` s 5 `<li>` elementy
- **`div.class#id`** - vytvoří `<div class="class" id="id">`
- **`table>tr*3>td*4`** - tabulka 3×4
- **`h1+p+p`** - `<h1>` a dva `<p>` za sebou
### Multi-cursor (ALT + klikání):
- Držte **ALT** a klikejte na různá místa
- Můžete psát text na více místech najednou
- Užitečné pro opakující se text
### Inline CSS:
```html
<!-- Inline CSS přímo v elementu -->
<h1 style="color: lime; background-color: purple;">Nadpis</h1>
<!-- Lepší je CSS v samostatném souboru (naučíte se v lekci 03) -->
```
## ⚠️ Důležité poznámky
- Tabulky se dnes používají **pouze pro tabulková data**, ne pro layout
- Pro layout použijte **CSS Grid** nebo **Flexbox** (naučíte se později)
- **Emmet** je součástí většiny editorů (VS Code, Sublime, Atom)
- Inline CSS je OK pro testování, ale pro produkci použijte externí CSS
## 🔗 Související lekce
- **Předchozí:** 01_uvod - základy HTML
- **Další:** 03_css_uvod - stylování pomocí CSS
- **Emmet dokumentace:** [Emmet Cheat Sheet](https://docs.emmet.io/cheat-sheet/)

53
03_css_uvod/README.md

@ -0,0 +1,53 @@
# 03 - Úvod do CSS
## 🎯 Co se naučíte
V této lekci se naučíte základy CSS (Cascading Style Sheets) - stylování webových stránek.
## 📚 Témata lekce
- **Připojení CSS** k HTML (external, internal, inline)
- **CSS selektory** (element, třída `.class`, ID `#id`)
- **Barvy** (`color`, `background-color`)
- **Text styling** (velikost, barva, zarovnání)
- **Kombinace tříd** (více tříd na jednom elementu)
- **Stylování seznamů a tabulek**
## 📂 Soubory v projektu
- `index.html` - HTML dokument s různými elementy
- `style.css` - CSS soubor s definicemi stylů
## 🎨 Ukázky v lekci
```css
/* Stylování třídou */
.fancyText { color: blue; }
/* Stylování ID */
#uniqueElement { font-size: 20px; }
/* Kombinace tříd */
.fancyText.fancyBG { ... }
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Prozkoumejte soubor `style.css` - zde jsou definovány styly
3. V HTML najděte atributy `class=""` a `style=""` - propojení s CSS
4. Zkuste změnit barvy, velikosti nebo přidat nové třídy
5. Vyzkoušejte kombinovat více tříd na jednom elementu
## 💡 Tip pro studenty
- **Inline CSS** (`style=""` přímo v HTML) - použijte jen výjimečně
- **External CSS** (samostatný soubor) - nejlepší pro větší projekty
- **Třída** (`.class`) - pro opakující se styly (můžete použít vícekrát)
- **ID** (`#id`) - pro unikátní element (použijte jen jednou na stránce)
- Element může mít více tříd najednou: `class="fancyText fancyBG"`
## 🔗 Související lekce
- **Předchozí:** 01_uvod, 02 - základy HTML
- **Další:** 04_layout - pokročilejší layout techniky

45
04_layout/README.md

@ -0,0 +1,45 @@
# 04 - CSS Layout
## 🎯 Co se naučíte
V této lekci se naučíte vytvářet layout (rozvržení) webové stránky pomocí CSS.
## 📚 Témata lekce
- **Box Model** (margin, padding, border)
- **Display property** (`block`, `inline`, `inline-block`)
- **Float** (obtékání elementů)
- **Clear** (ukončení obtékání)
- **Width a Height** (šířka a výška elementů)
- **Základní layouty** (dvousloupcový, třísloupcový)
## 📂 Soubory v projektu
- `index.html` - HTML struktura s layoutem
- `style.css` nebo `css/` složka - CSS styly pro layout
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Prozkoumejte CSS - zaměřte se na vlastnosti `float`, `clear`, `width`
3. Použijte Developer Tools (F12) a vyzkoušejte Box Model vizualizaci
4. Zkuste změnit šířky sloupců a sledujte, jak se mění layout
## 💡 Tip pro studenty
- **Box Model**: `margin` (vnější odsazení) ≠ `padding` (vnitřní odsazení)
- **Float** je starší technika - dnes se používá spíše Flexbox nebo Grid
- Nezapomeňte používat `clear: both;` po float elementech
- Developer Tools (F12) jsou váš nejlepší přítel pro debugování layoutu
## ⚠️ Důležité poznámky
- Float-based layout je starší přístup
- V moderních projektech se používá **Flexbox** (lekce 10) nebo **Grid** (lekce 12)
- Tato lekce je důležitá pro pochopení starších projektů
## 🔗 Související lekce
- **Předchozí:** 03_css_uvod - základy CSS
- **Další:** 10_flex - moderní flexbox layout
- **Související:** 12_grid - CSS Grid systém

71
05_js_intro/README.md

@ -0,0 +1,71 @@
# 05 - Úvod do JavaScriptu
## 🎯 Co se naučíte
V této lekci se seznámíte se základy programování v JavaScriptu.
## 📚 Témata lekce
- **Připojení JavaScriptu** k HTML (inline, external)
- **Console.log** - výpis do konzole (F12)
- **Proměnné** (`let`, `const`, `var`)
- **Datové typy**:
- Čísla (number)
- Texty (string)
- Pole (array)
- Objekty (object)
- Datum (Date)
- **Podmínky** (`if`, `else`, `&&`, `||`)
- **Cykly** (`for`)
- **Funkce** (definice a volání)
## 📂 Soubory v projektu
- `index.html` - HTML soubor s připojením JS
- `app.js` - JavaScript soubor s ukázkami základů
## 💻 Ukázky v lekci
```javascript
// Proměnné
let x = 5;
const jmeno = "Jan";
// Podmínky
if (x > 3) {
console.log("x je větší než 3");
}
// Funkce
function pozdrav() {
console.log("Ahoj!");
}
pozdrav(); // volání funkce
// Cyklus
for (let i = 0; i < 5; i++) {
console.log(i);
}
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Otevřete **Developer Console** (F12 → záložka Console)
3. Prohlédněte si soubor `app.js` v editoru
4. Zkuste měnit hodnoty proměnných a sledujte výstup v konzoli
5. Vytvořte vlastní funkce a zavolejte je
6. Experimentujte s podmínkami a cykly
## 💡 Tip pro studenty
- **Console.log()** je váš nejlepší přítel při debugování
- **let** vs **const**: použijte `const` pro hodnoty, které se nemění
- **var** se dnes už moc nepoužívá - používejte `let` nebo `const`
- Nezapomeňte volat funkci pomocí závorek: `nazevFunkce()`
- Pro objekty používáme tečkovou notaci: `osobnost.jmeno`
## 🔗 Související lekce
- **Další:** 06_js_html - propojení JavaScriptu s HTML elementy
- **Související:** 07_js_css_dom - manipulace s CSS přes JavaScript

62
06_js_html/README.md

@ -0,0 +1,62 @@
# 06 - JavaScript a HTML
## 🎯 Co se naučíte
V této lekci se naučíte propojit JavaScript s HTML elementy a vytvořit interaktivní kalkulačku.
## 📚 Témata lekce
- **getElementById()** - získání elementu podle ID
- **innerHTML** - změna obsahu elementu
- **innerText** - změna textu elementu
- **onclick** - obsluha kliknutí na tlačítko
- **Input elementy** - čtení hodnot z formulářových polí
- **Number()** - převod textu na číslo
- **Matematické operace** v JavaScriptu
## 📂 Soubory v projektu
- `index.html` - HTML s inputy a tlačítky
- `js/app.js` - JavaScript s funkcí pro výpočet
## 💻 Ukázka z lekce
```html
<!-- HTML -->
<input type="number" id="num1" placeholder="Číslo 1">
<button onclick="vypocitat('+')">SEČÍST</button>
<span id="vysledek"></span>
```
```javascript
// JavaScript
function vypocitat(operator) {
let cislo1 = document.getElementById("num1").value;
let cislo2 = document.getElementById("num2").value;
// výpočet a zobrazení výsledku
document.getElementById("vysledek").innerHTML = vysledek;
}
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Vyzkoušejte kalkulačku - zadejte čísla a klikněte na tlačítka
3. Otevřete `js/app.js` a prozkoumejte funkci `vypocitat()`
4. Sledujte, jak se hodnoty čtou z inputů pomocí `getElementById()`
5. Zkuste přidat další operace (mocnina, odmocnina)
6. Použijte Developer Console (F12) pro debugování
## 💡 Tip pro studenty
- **getElementById()** vrací element, ne hodnotu - musíte použít `.value`
- **onclick** můžete použít přímo v HTML: `onclick="nazevFunkce()"`
- Hodnoty z inputů jsou vždy **string** - použijte `Number()` pro převod
- **innerHTML** vs **innerText**: innerHTML umožňuje HTML tagy, innerText jen text
- Používejte **console.log()** pro kontrolu hodnot při vývoji
## 🔗 Související lekce
- **Předchozí:** 05_js_intro - základy JavaScriptu
- **Další:** 07_js_css_dom - manipulace s CSS přes JavaScript
- **Související:** 08_js_form - práce s formuláři

85
07_js_css_dom/README.md

@ -0,0 +1,85 @@
# 07 - JavaScript, CSS a DOM
## 🎯 Co se naučíte
V této lekci se naučíte měnit CSS styly pomocí JavaScriptu a pracovat s DOM (Document Object Model).
## 📚 Témata lekce
- **DOM (Document Object Model)** - struktura HTML v JavaScriptu
- **style.property** - změna CSS vlastností přes JS
- **onchange** event - reakce na změnu hodnoty
- **Select element** - práce s rozbalovacím seznamem
- **Input type="color"** - barevný picker
- **Dynamická změna stylů** (barva textu, barva pozadí, font)
## 📂 Soubory v projektu
- `index.html` - HTML s select elementy a color pickery
- `css/style.css` - základní CSS styly
- `js/index.js` - JavaScript pro změnu barev
- `js/changeFont.js` - JavaScript pro změnu fontu
## 💻 Ukázka z lekce
```html
<!-- HTML -->
<p id="ltext">Lorem ipsum...</p>
<select id="scolor" onchange="changeSColor()">
<option value="black">černá</option>
<option value="red">červená</option>
</select>
<input type="color" id="tcolor" onchange="dynColor()">
```
```javascript
// JavaScript
function changeSColor() {
let element = document.getElementById("ltext");
let barva = document.getElementById("scolor").value;
element.style.color = barva;
}
function dynColor() {
let element = document.getElementById("ltext");
let barva = document.getElementById("tcolor").value;
element.style.color = barva;
}
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Vyzkoušejte měnit barvu textu pomocí selectu a color pickeru
3. Změňte font pomocí selectu
4. Prozkoumejte JS soubory - jak se elementy mění pomocí `.style`
5. Zkuste přidat další styly (velikost textu, tučnost, kurzíva)
6. Experimentujte s různými CSS vlastnostmi
## 💡 Tip pro studenty
- **element.style.property** - property musí být v camelCase:
- CSS: `background-color` → JS: `backgroundColor`
- CSS: `font-size` → JS: `fontSize`
- **onchange** se spouští při změně hodnoty (select, input)
- **input type="color"** vrací hodnotu v HEX formátu (#000000)
- Používejte **Developer Tools** (F12) → Elements → Styles pro inspekci CSS
## 🎨 CSS vlastnosti, které můžete měnit přes JS
```javascript
element.style.color = "red";
element.style.backgroundColor = "blue";
element.style.fontSize = "20px";
element.style.fontFamily = "Arial";
element.style.fontWeight = "bold";
element.style.textAlign = "center";
element.style.padding = "10px";
element.style.margin = "5px";
```
## 🔗 Související lekce
- **Předchozí:** 06_js_html - propojení JS a HTML
- **Další:** 08_js_form - validace formulářů s JavaScriptem
- **Související:** 05_js_intro - základy JavaScriptu

94
08_js_form/README.md

@ -0,0 +1,94 @@
# 08 - JavaScript a Formuláře
## 🎯 Co se naučíte
V této lekci se naučíte pracovat s formuláři v JavaScriptu - validace, odeslání, manipulace s daty.
## 📚 Témata lekce
- **Formulářové elementy** (input, textarea, select, checkbox, radio)
- **Validace formulářů** s JavaScriptem
- **event.preventDefault()** - zabránění odeslání formuláře
- **Čtení hodnot** z různých typů inputů
- **Kontrola povinných polí**
- **Regex** (základy) - kontrola formátu emailu, telefonu
- **Visual feedback** - zobrazení chyb uživateli
## 📂 Soubory v projektu
- `index.html` - HTML formulář
- `js/` - JavaScript soubory pro validaci
## 💻 Ukázka z lekce
```html
<!-- HTML -->
<form id="myForm" onsubmit="return validateForm()">
<input type="text" id="jmeno" required>
<input type="email" id="email" required>
<button type="submit">Odeslat</button>
</form>
<p id="error"></p>
```
```javascript
// JavaScript
function validateForm() {
let jmeno = document.getElementById("jmeno").value;
let email = document.getElementById("email").value;
if (jmeno === "") {
document.getElementById("error").innerHTML = "Jméno je povinné!";
return false; // zabrání odeslání
}
// Regex pro email
let emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
document.getElementById("error").innerHTML = "Neplatný email!";
return false;
}
return true; // formulář se odešle
}
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Vyzkoušejte odeslat formulář s prázdnými poli
3. Sledujte validační zprávy
4. Prozkoumejte JS kód - jak funguje validace
5. Zkuste přidat další validace (délka hesla, shoda hesel)
6. Použijte console.log() pro debugování
## 💡 Tip pro studenty
- **return false** v `onsubmit` zabrání odeslání formuláře
- **event.preventDefault()** je modernější způsob zabránění odeslání
- **required** atribut v HTML je první úroveň validace (HTML5)
- **JavaScript validace** je důležitá pro pokročilejší kontroly
- **Regex** (regulární výrazy) jsou mocný nástroj pro validaci formátů
- Vždy validujte i na **serveru** - JavaScript validace lze obejít
## 🔍 Užitečné Regex vzory
```javascript
// Email
/^[^\s@]+@[^\s@]+\.[^\s@]+$/
// Telefon (CZ formát)
/^(\+420)?[0-9]{9}$/
// Heslo (min 8 znaků, velké, malé, číslo)
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/
// Poštovní směrovací číslo
/^[0-9]{3}\s?[0-9]{2}$/
```
## 🔗 Související lekce
- **Předchozí:** 07_js_css_dom - manipulace s CSS
- **Související:** AI/ai_03_form_validation - pokročilá validace s addEventListener
- **Další:** 11_json - práce s JSON daty

100
09_mediaquerry/README.md

@ -0,0 +1,100 @@
# 09 - Media Queries a Responzivní Design
## 🎯 Co se naučíte
V této lekci se naučíte vytvářet responzivní webové stránky pomocí media queries.
## 📚 Témata lekce
- **Media Queries** - CSS pravidla pro různé velikosti obrazovek
- **Viewport meta tag** - důležitý pro responzivitu
- **Breakpointy** - body zlomu pro různá zařízení
- **Mobile-first přístup** vs Desktop-first
- **Responzivní obrázky** - přizpůsobení velikosti
- **Responzivní layout** - změna rozvržení podle velikosti
## 📂 Soubory v projektu
- `index.html` - HTML s viewport meta tagem
- `style.css` - CSS s media queries
- `img/` - složka s obrázky
## 💻 Ukázka z lekce
```html
<!-- HTML - DŮLEŽITÝ viewport meta tag! -->
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
```
```css
/* CSS - Media Queries */
/* Desktop styly (výchozí) */
.col-6 {
width: 50%;
float: left;
}
/* Tablet (do 768px) */
@media (max-width: 768px) {
.col-6 {
width: 100%;
}
}
/* Mobil (do 480px) */
@media (max-width: 480px) {
.col-6 {
width: 100%;
}
body {
font-size: 14px;
}
}
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Otevřete **Developer Tools** (F12) a zapněte **Device Toolbar** (Ctrl+Shift+M)
3. Změňte velikost okna nebo vyberte různá zařízení (iPhone, iPad, Desktop)
4. Sledujte, jak se mění layout při různých velikostech
5. Prozkoumejte `style.css` - najděte `@media` pravidla
6. Zkuste přidat vlastní breakpointy a změny stylů
## 💡 Tip pro studenty
- **VŽDY použijte viewport meta tag** - bez něj responzivita na mobilu nebude fungovat!
- **Breakpointy** (běžné hodnoty):
- Mobil: `max-width: 480px`
- Tablet: `max-width: 768px`
- Desktop: `min-width: 769px` nebo bez media query
- **Mobile-first** přístup (doporučený):
- Výchozí styly pro mobil
- Media queries s `min-width` pro větší obrazovky
- **Desktop-first** přístup:
- Výchozí styly pro desktop
- Media queries s `max-width` pro menší obrazovky
- Testujte na **reálných zařízeních**, ne jen v prohlížeči
## 📱 Testování responzivity
**V prohlížeči:**
1. F12 → Device Toolbar (Ctrl+Shift+M)
2. Vyberte zařízení nebo nastavte vlastní rozměry
3. Otočte zařízení (landscape/portrait)
**Běžné rozlišení:**
- iPhone: 375px × 667px
- iPad: 768px × 1024px
- Desktop: 1920px × 1080px
## 🔗 Související lekce
- **Předchozí:** 08_js_form - JavaScript a formuláře
- **Další:** 10_flex - Flexbox layout
- **Související:**
- 12_grid - CSS Grid (další layout systém)
- AI/ai_01_grid_responsive - praktický projekt s responzivitou

129
10_flex/README.md

@ -0,0 +1,129 @@
# 10 - Flexbox Layout
## 🎯 Co se naučíte
V této lekci se naučíte vytvářet moderní layouty pomocí CSS Flexbox.
## 📚 Témata lekce
- **Flexbox základy** - `display: flex`
- **Flex container** vlastnosti:
- `flex-direction` (row, column)
- `justify-content` (zarovnání na hlavní ose)
- `align-items` (zarovnání na vedlejší ose)
- `flex-wrap` (zalamování položek)
- `gap` (mezery mezi položkami)
- **Flex items** vlastnosti:
- `flex-grow`, `flex-shrink`, `flex-basis`
- `align-self` (individuální zarovnání)
- **Praktické použití** - navigace, karty, layout
## 📂 Soubory v projektu
- `index.html` - HTML struktura s flexbox layoutem
- `style.css` - CSS s flexbox vlastnostmi
## 💻 Ukázka z lekce
```css
/* Flex container */
.wrapper {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 20px;
}
/* Flex items */
.main {
flex: 2; /* flex-grow: 2 */
}
.aside {
flex: 1; /* flex-grow: 1 */
}
/* Navigace s flexbox */
.navigace {
display: flex;
justify-content: space-between;
align-items: center;
}
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Otevřete **Developer Tools** (F12) a vyberte flexbox element
3. V Chrome DevTools najdete **Flexbox** badge - klikněte pro vizualizaci
4. Prozkoumejte `style.css` - jak funguje `display: flex`
5. Zkuste měnit `flex-direction`, `justify-content`, `align-items`
6. Změňte velikost okna a sledujte, jak se flex items přizpůsobují
## 💡 Tip pro studenty
### Kdy použít Flexbox:
- ✅ Navigační menu (horizontální nebo vertikální)
- ✅ Karty/produkty vedle sebe
- ✅ Centrování elementů (horizontálně i vertikálně)
- ✅ Jednosměrné layouty (řádek nebo sloupec)
### Kdy raději Grid:
- ❌ Komplexní dvourozměrné layouty (řádky + sloupce)
- ❌ Galerie obrázků
- ❌ Celostránkové layouty s header, sidebar, main, footer
### Hlavní koncept:
- **Flex container** = rodič s `display: flex`
- **Flex items** = přímé potomci flex containeru
### Důležité vlastnosti:
```css
/* Na kontejneru */
display: flex;
justify-content: center; /* horizontální zarovnání */
align-items: center; /* vertikální zarovnání */
gap: 20px; /* mezery mezi položkami */
/* Na položkách */
flex: 1; /* roztáhne položku */
```
## 🎯 Praktické příklady
**Centrování:**
```css
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
```
**Horizontální navigace:**
```css
nav {
display: flex;
justify-content: space-between;
}
```
**Responzivní karty:**
```css
.card-container {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
flex: 1 1 300px; /* min šířka 300px */
}
```
## 🔗 Související lekce
- **Předchozí:** 09_mediaquerry - responzivní design
- **Další:** 11_json - práce s JSON
- **Porovnání:** 12_grid - CSS Grid (dvourozměrný layout)
- **Praktický projekt:** AI/ai_04_prep_bootstrap - kombinace Flex a Grid

117
11_json/README.md

@ -0,0 +1,117 @@
# 11 - JSON a Práce s Daty
## 🎯 Co se naučíte
V této lekci se naučíte pracovat s JSON formátem a načítat data do JavaScriptu.
## 📚 Témata lekce
- **JSON formát** (JavaScript Object Notation)
- **JSON.parse()** - převod JSON stringu na objekt
- **JSON.stringify()** - převod objektu na JSON string
- **Načítání dat z JSON souborů**
- **Práce s JSON daty** v JavaScriptu
- **Výpis dat na stránku** pomocí DOM manipulace
- **Pole objektů** - procházení cyklem
## 📂 Soubory v projektu
- `index.html` - HTML s elementy pro zobrazení dat
- `js/app.js` - JavaScript pro práce s JSON
- `data/` (možná) - složka s JSON soubory
## 💻 Ukázka z lekce
```javascript
// JSON objekt v JavaScriptu
const osoba = {
"jmeno": "Jan",
"prijmeni": "Novák",
"vek": 20,
"mesto": "Praha"
};
// Výpis dat
console.log(osoba.jmeno); // Jan
// JSON string
const jsonString = '{"jmeno":"Jan","vek":20}';
// Převod stringu na objekt
const obj = JSON.parse(jsonString);
console.log(obj.jmeno); // Jan
// Převod objektu na string
const str = JSON.stringify(osoba);
console.log(str); // {"jmeno":"Jan",...}
// Pole objektů
const osoby = [
{"jmeno": "Jan", "vek": 20},
{"jmeno": "Petra", "vek": 25},
{"jmeno": "Karel", "vek": 30}
];
// Procházení pole
osoby.forEach(function(osoba) {
console.log(osoba.jmeno + " má " + osoba.vek + " let");
});
// Výpis na stránku
let html = "";
osoby.forEach(function(osoba) {
html += "<p>" + osoba.jmeno + "</p>";
});
document.getElementById("demo").innerHTML = html;
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Otevřete **Console** (F12) a sledujte výpis JSON dat
3. Prozkoumejte `js/app.js` - jak se pracuje s JSON
4. Zkuste vytvořit vlastní JSON objekt
5. Vyzkoušejte převody mezi objektem a stringem
6. Vytvořte pole objektů a vypište je na stránku
## 💡 Tip pro studenty
### JSON syntaxe:
- **Klíče musí být v uvozovkách**: `{"jmeno": "Jan"}`
- **Hodnoty**: string (v uvozovkách), číslo, boolean, null, objekt, pole
- **Čárka** mezi položkami, ale ne za poslední
- **Žádné komentáře** v JSON!
### Běžné chyby:
```javascript
// ❌ ŠPATNĚ - klíče bez uvozovek
{jmeno: "Jan"}
// ✅ SPRÁVNĚ
{"jmeno": "Jan"}
// ❌ ŠPATNĚ - čárka za posledním
{"jmeno": "Jan", "vek": 20,}
// ✅ SPRÁVNĚ
{"jmeno": "Jan", "vek": 20}
```
### JSON vs JavaScript objekt:
- **JSON** = textový formát (string), univerzální
- **JS objekt** = datová struktura v paměti
- **JSON.parse()** = převod z textu na objekt
- **JSON.stringify()** = převod z objektu na text
### Praktické použití:
- 💾 Ukládání dat do localStorage
- 🌐 Komunikace s API (fetch)
- 📤 Odesílání dat na server
- 📥 Načítání konfigurace
## 🔗 Související lekce
- **Předchozí:** 10_flex - Flexbox layout
- **Další:** 12_grid - CSS Grid
- **Pokročilé:** 20_ajax - AJAX a Fetch API (načítání JSON ze serveru)
- **Praktické:** Práce s API a reálnými JSON daty

150
12_grid/README.md

@ -0,0 +1,150 @@
# 12 - CSS Grid Layout
## 🎯 Co se naučíte
V této lekci se naučíte vytvářet komplexní dvourozměrné layouty pomocí CSS Grid.
## 📚 Témata lekce
- **CSS Grid základy** - `display: grid`
- **Grid container** vlastnosti:
- `grid-template-columns` (definice sloupců)
- `grid-template-rows` (definice řádků)
- `gap`, `column-gap`, `row-gap` (mezery)
- `grid-template-areas` (pojmenované oblasti)
- **Grid items** vlastnosti:
- `grid-column`, `grid-row` (umístění položky)
- `grid-area` (pojmenovaná oblast)
- **Responzivní Grid** - kombinace s media queries
- **Galerie** - praktické použití Gridu
## 📂 Soubory v projektu
- `index.html` - HTML s grid strukturou
- `style.css` - CSS s grid definicemi
## 💻 Ukázka z lekce
```css
/* Grid container - galerie */
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 stejně široké sloupce */
gap: 20px; /* mezery mezi položkami */
}
/* Grid items */
.grid-item {
background-color: lightblue;
padding: 20px;
}
/* První položka zabere 2 sloupce */
.grid-item:first-child {
grid-column: span 2;
}
/* Responzivní Grid */
@media (max-width: 768px) {
.grid-container {
grid-template-columns: repeat(2, 1fr); /* 2 sloupce na tabletu */
}
}
@media (max-width: 480px) {
.grid-container {
grid-template-columns: 1fr; /* 1 sloupec na mobilu */
}
}
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Otevřete **Developer Tools** (F12) a vyberte grid element
3. V Chrome DevTools najdete **Grid** badge - klikněte pro vizualizaci mřížky
4. Prozkoumejte `style.css` - jak funguje `display: grid`
5. Zkuste měnit počet sloupců: `grid-template-columns: repeat(4, 1fr)`
6. Experimentujte s `gap`, `grid-column`, `grid-row`
7. Změňte velikost okna a sledujte responzivitu
## 💡 Tip pro studenty
### Kdy použít Grid:
- ✅ Komplexní dvourozměrné layouty (řádky + sloupce)
- ✅ Galerie obrázků
- ✅ Celostránkové layouty (header, sidebar, main, footer)
- ✅ Dashboardy, karty v mřížce
- ✅ Kalendáře
### Kdy raději Flexbox:
- ❌ Jednosměrné layouty (jen řádek nebo jen sloupec)
- ❌ Navigační menu
- ❌ Jednoduchá centrování
### Hlavní jednotky:
- **fr** (fraction) = podíl dostupného prostoru
- `1fr 2fr` = první sloupec 1/3, druhý 2/3
- **px** = pevná velikost
- **%** = procenta z containeru
- **auto** = automatická velikost podle obsahu
### Grid layout pattern:
```css
/* Kontejner */
.grid-container {
display: grid; /* MUSÍ BÝT! */
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
/* Položky se umístí automaticky */
.grid-item {
/* žádné speciální vlastnosti potřeba */
}
```
## 🎯 Praktické příklady
**Galerie 3 sloupce:**
```css
.galerie {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
```
**Responzivní galerie (bez media queries!):**
```css
.galerie {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
```
**Layout stránky:**
```css
.layout {
display: grid;
grid-template-columns: 250px 1fr; /* sidebar + main */
grid-template-rows: 80px 1fr 60px; /* header + content + footer */
gap: 10px;
height: 100vh;
}
```
## ⚠️ Důležité poznámky
1. **display: grid musí být na KONTEJNERU**, ne na položkách!
2. **Grid položky** = pouze přímé děti grid containeru
3. Použijte **Chrome DevTools Grid inspector** pro debugování
4. **repeat()** funkce šetří psaní: `repeat(3, 1fr)` = `1fr 1fr 1fr`
## 🔗 Související lekce
- **Předchozí:** 11_json - práce s JSON
- **Další:** 13_bootstrap_intro - úvod do Bootstrapu
- **Porovnání:** 10_flex - Flexbox (jednosměrný layout)
- **Praktický projekt:** AI/ai_01_grid_responsive - kompletní Grid projekt s responzivitou

119
13_boostrap_intro/README.md

@ -0,0 +1,119 @@
# 13 - Úvod do Bootstrapu
## 🎯 Co se naučíte
V této lekci se seznámíte s Bootstrap frameworkem a jeho základními komponentami.
## 📚 Témata lekce
- **Co je Bootstrap** - CSS framework pro rychlý vývoj
- **Připojení Bootstrapu** k projektu (lokální soubory)
- **Container** - základní obal pro obsah (`.container`)
- **Grid systém** - 12sloupcová mřížka
- `.row` - řádek
- `.col` - sloupce (automatická šířka)
- `.col-6` - sloupec se šířkou 6/12
- **Responzivní třídy** - `col-md-6`, `col-lg-3`
- **Typography** - `display-1`, `display-5`
- **Utility třídy**:
- Okraje: `m-2`, `mx-2`, `p-2`
- Borders: `border`, `border-danger`, `rounded`
- Další: `<mark>`, `<code>`, `<kbd>`
## 📂 Soubory v projektu
- `index.html` - HTML s Bootstrap třídami
- `css/bootstrap.css` - Bootstrap CSS (lokální)
- `js/bootstrap.js` - Bootstrap JavaScript (lokální)
## 💻 Ukázka z lekce
```html
<!-- Container -->
<div class="container">
<h1 class="display-1">Hello, Bootstrap!</h1>
<!-- Grid systém -->
<div class="row">
<div class="col-md-6 col-lg-3">
<div class="border border-primary rounded m-2 p-2">
Obsah sloupce
</div>
</div>
<div class="col-md-6 col-lg-3">
Další sloupec
</div>
</div>
</div>
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Prozkoumejte Bootstrap třídy v HTML
3. Změňte velikost okna - sledujte responzivní chování
4. Vyzkoušejte Developer Tools (F12) - Device Toolbar
5. Experimentujte s různými utility třídami
6. Změňte `col-md-6` na `col-lg-4` a sledujte změny
## 💡 Tip pro studenty
### Bootstrap Grid System:
- **12 sloupců celkem** v každém řádku
- **col-6** = 6/12 = 50% šířky
- **col-4** = 4/12 = 33.33% šířky
- **col** = automatická šířka (rovnoměrně rozdělí prostor)
### Responzivní breakpointy:
- **xs** (extra small) = < 576px (mobil) - není třeba psát, je výchozí
- **sm** (small) = ≥ 576px
- **md** (medium) = ≥ 768px (tablet)
- **lg** (large) = ≥ 992px (desktop)
- **xl** (extra large) = ≥ 1200px
### Příklad responzivity:
```html
<div class="col-12 col-md-6 col-lg-3">
<!-- Mobil: 100% šířky (12/12) -->
<!-- Tablet: 50% šířky (6/12) -->
<!-- Desktop: 25% šířky (3/12) -->
</div>
```
### Container vs Container-fluid:
- **container** = fixní šířka, centrovaný
- **container-fluid** = 100% šířky
### Důležité:
- VŽDY používejte **row** pro řádky
- Sloupce (**col**) musí být uvnitř **row**
- Celkový součet sloupců by měl být **12** (nebo méně)
## 🎨 Utility třídy:
```html
<!-- Okraje (margin) -->
m-2 = margin všude
mx-2 = margin vlevo a vpravo
my-3 = margin nahoře a dole
mt-4 = margin nahoře
<!-- Padding -->
p-2 = padding všude
px-3 = padding vlevo a vpravo
<!-- Borders -->
border = přidá border
border-primary = modrý border
border-3 = tlustší border
rounded = zaoblené rohy
```
## 🔗 Související lekce
- **Předchozí:** 12_grid - CSS Grid (pochopení grid systému)
- **Důležité přípravné projekty:**
- AI/ai_01_grid_responsive - CSS Grid praxe
- AI/ai_04_prep_bootstrap - komplexní příprava
- **Další:** 14_bootstrap_layout - pokročilejší Bootstrap layouty
- **Související:** 15_bootstrap_components - Bootstrap komponenty

162
14_bootstrap_layout/README.md

@ -0,0 +1,162 @@
# 14 - Bootstrap Layout
## 🎯 Co se naučíte
V této lekci se naučíte vytvářet kompletní layout stránky s pomocí Bootstrapu.
## 📚 Témata lekce
- **Header s navigací** - `nav`, `nav-pills`, `nav-item`
- **Flexbox utility třídy** - `d-flex`, `justify-content-center`, `align-items-center`
- **Main content** - hlavní obsah stránky
- **Jumbotron** - velká úvodní sekce (hero section)
- **Tabulky** - `table`, `table-hover`, `table-dark`, `table-info`
- **Footer** - patička stránky s `mt-auto`
- **Sticky footer** - přilepený footer (flexbox pattern)
- **Buttons** - `btn`, `btn-primary`
## 📂 Soubory v projektu
- `index.html` - kompletní layout s header, main, footer
- `css/bootstrap.css` - Bootstrap CSS
- `js/bootstrap.js` - Bootstrap JS
## 💻 Ukázka z lekce
```html
<body class="d-flex flex-column min-vh-100">
<!-- Header -->
<header class="d-flex flex-wrap justify-content-center py-3 border-bottom">
<a href="#" class="me-auto fs-4">Název Stránky</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a href="#" class="nav-link active">Home</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link">About</a>
</li>
</ul>
</header>
<!-- Main -->
<main class="container">
<!-- Jumbotron -->
<div class="p-5 bg-secondary text-white rounded">
<h1 class="display-3">Hello world!</h1>
<p>Lorem ipsum...</p>
<a href="#" class="btn btn-primary">Více info</a>
</div>
<!-- Tabulka -->
<table class="table table-hover">
<tr class="table-dark">
<td>Jméno</td>
<td>Email</td>
</tr>
<tr class="table-info">
<td>Jan</td>
<td>jan@email.cz</td>
</tr>
</table>
</main>
<!-- Footer -->
<footer class="footer mt-auto">
<div class="nav justify-content-center py-2">
<span>© 2025</span>
</div>
</footer>
</body>
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Prozkoumejte strukturu: header → main → footer
3. Změňte velikost okna - sledujte responzivní navigaci
4. Vyzkoušejte hover efekt na tabulce
5. Experimentujte s barevnými třídami tabulek
6. Zkuste přidat další navigační položky
## 💡 Tip pro studenty
### Sticky Footer pattern:
```html
<body class="d-flex flex-column min-vh-100">
<header>...</header>
<main class="container">...</main>
<footer class="footer mt-auto">...</footer>
</body>
```
- **d-flex flex-column** = flexbox ve vertikálním směru
- **min-vh-100** = minimální výška 100% viewportu
- **mt-auto** = margin-top: auto (footer se přilepí dolů)
### Flexbox utility třídy:
```html
<!-- Display -->
d-flex = display: flex
d-inline-flex = display: inline-flex
<!-- Direction -->
flex-row = řádkový (výchozí)
flex-column = sloupcový
<!-- Justify content (horizontální zarovnání) -->
justify-content-start = vlevo
justify-content-center = na střed
justify-content-end = vpravo
justify-content-between = mezi
<!-- Align items (vertikální zarovnání) -->
align-items-start = nahoře
align-items-center = na střed
align-items-end = dole
```
### Navigace:
```html
<ul class="nav nav-pills">
<li class="nav-item">
<a href="#" class="nav-link active">Aktivní odkaz</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link disabled">Neaktivní odkaz</a>
</li>
</ul>
```
### Tabulky:
```html
<!-- Základní tabulka -->
<table class="table">...</table>
<!-- S hover efektem -->
<table class="table table-hover">...</table>
<!-- Barevné řádky -->
<tr class="table-primary">...</tr> <!-- modrá -->
<tr class="table-success">...</tr> <!-- zelená -->
<tr class="table-danger">...</tr> <!-- červená -->
<tr class="table-warning">...</tr> <!-- žlutá -->
<tr class="table-info">...</tr> <!-- světle modrá -->
<tr class="table-dark">...</tr> <!-- tmavá -->
```
### Buttons:
```html
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-success">Success</button>
<button class="btn btn-danger">Danger</button>
<button class="btn btn-warning">Warning</button>
<button class="btn btn-outline-primary">Outline</button>
```
## 🔗 Související lekce
- **Předchozí:** 13_bootstrap_intro - úvod do Bootstrapu
- **Další:** 15_bootstrap_components - Bootstrap komponenty
- **Související:**
- 10_flex - Flexbox (pochopení flexbox utility tříd)
- AI/ai_02_semantic_portfolio - sémantická struktura stránky

165
15_bootstrap_components/README.md

@ -0,0 +1,165 @@
# 15 - Bootstrap Komponenty
## 🎯 Co se naučíte
V této lekci se naučíte používat základní Bootstrap komponenty pro vytváření interaktivních webů.
## 📚 Témata lekce
- **Cards** - kartičky pro obsah
- **Buttons** - tlačítka různých stylů
- **Badges** - odznaky pro zvýraznění
- **Alerts** - upozornění a zprávy
- **Progress bars** - indikátory průběhu
- **Breadcrumbs** - navigační drobečková navigace
- **Pagination** - stránkování
- **List groups** - stylované seznamy
- **Forms** - formulářové komponenty
## 📂 Soubory v projektu
- `index.html` - ukázky Bootstrap komponent
- `css/bootstrap.css` - Bootstrap CSS
- `js/bootstrap.js` - Bootstrap JS
## 💻 Ukázky komponent
### Cards (Kartičky)
```html
<div class="card" style="width: 18rem;">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Nadpis karty</h5>
<p class="card-text">Text karty...</p>
<a href="#" class="btn btn-primary">Tlačítko</a>
</div>
</div>
```
### Alerts
```html
<div class="alert alert-primary" role="alert">
Primární alert
</div>
<div class="alert alert-success" role="alert">
Úspěšná operace!
</div>
<div class="alert alert-danger" role="alert">
Chyba!
</div>
```
### Badges
```html
<h1>Nadpis <span class="badge bg-secondary">Nový</span></h1>
<button class="btn btn-primary">
Notifikace <span class="badge bg-danger">4</span>
</button>
```
### Progress Bar
```html
<div class="progress">
<div class="progress-bar" role="progressbar"
style="width: 75%" aria-valuenow="75"
aria-valuemin="0" aria-valuemax="100">75%</div>
</div>
<!-- Barevné -->
<div class="progress">
<div class="progress-bar bg-success" style="width: 50%">50%</div>
</div>
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Prozkoumejte různé komponenty
3. Vyzkoušejte změnit barvy komponent (primary → success)
4. Experimentujte s kombinacemi komponent
5. Zkuste vytvořit vlastní kartu s obrázkem a tlačítkem
6. Prozkoumejte Bootstrap dokumentaci pro více variant
## 💡 Tip pro studenty
### Card layout:
```html
<!-- Grid s kartami -->
<div class="row">
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Karta 1</h5>
<p class="card-text">Obsah...</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">...</div>
</div>
<div class="col-md-4">
<div class="card">...</div>
</div>
</div>
```
### Bootstrap barvy (color variants):
Většina komponent podporuje barevné varianty:
- **primary** = modrá (hlavní)
- **secondary** = šedá
- **success** = zelená (úspěch)
- **danger** = červená (chyba)
- **warning** = žlutá (varování)
- **info** = světle modrá (info)
- **light** = světlá
- **dark** = tmavá
### List Groups:
```html
<ul class="list-group">
<li class="list-group-item">První položka</li>
<li class="list-group-item active">Aktivní položka</li>
<li class="list-group-item">Třetí položka</li>
</ul>
```
### Breadcrumbs:
```html
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item"><a href="#">Produkty</a></li>
<li class="breadcrumb-item active">Notebook</li>
</ol>
</nav>
```
### Pagination:
```html
<nav>
<ul class="pagination">
<li class="page-item"><a class="page-link" href="#">Předchozí</a></li>
<li class="page-item"><a class="page-link" href="#">1</a></li>
<li class="page-item active"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item"><a class="page-link" href="#">Další</a></li>
</ul>
</nav>
```
## 🎨 Praktické využití
**E-shop produkty** = Cards
**Úspěšné odeslání formuláře** = Alert success
**Počet položek v košíku** = Badge
**Upload souboru** = Progress bar
**Navigace kategoriemi** = Breadcrumbs
**Seznam článků** = Pagination
## 🔗 Související lekce
- **Předchozí:** 14_bootstrap_layout - Bootstrap layout
- **Další:**
- 16_carousel - Bootstrap carousel (slider)
- 17_modal - Bootstrap modal (okna)
- **Dokumentace:** [Bootstrap Components](https://getbootstrap.com/docs/5.3/components/)

171
16_carousel/README.md

@ -0,0 +1,171 @@
# 16 - Bootstrap Carousel
## 🎯 Co se naučíte
V této lekci se naučíte vytvářet carousel (slider/slideshow) pomocí Bootstrapu.
## 📚 Témata lekce
- **Carousel** - posuvný slider obrázků
- **Carousel indicators** - indikátory snímků (tečky)
- **Carousel controls** - ovládací šipky
- **Carousel captions** - popisky k obrázkům
- **Auto-sliding** - automatické přepínání
- **JavaScript carousel API** - ovládání přes JS
- **Data attributes** - `data-bs-ride`, `data-bs-slide-to`
## 📂 Soubory v projektu
- `index.html` - HTML s carousel komponentou
- `css/bootstrap.css` - Bootstrap CSS
- `js/bootstrap.js` - Bootstrap JS (DŮLEŽITÝ pro carousel!)
- `images/` - obrázky pro carousel
## 💻 Základní Carousel
```html
<div id="carouselExample" class="carousel slide" data-bs-ride="carousel">
<!-- Indikátory (tečky) -->
<div class="carousel-indicators">
<button type="button" data-bs-target="#carouselExample"
data-bs-slide-to="0" class="active"></button>
<button type="button" data-bs-target="#carouselExample"
data-bs-slide-to="1"></button>
<button type="button" data-bs-target="#carouselExample"
data-bs-slide-to="2"></button>
</div>
<!-- Snímky -->
<div class="carousel-inner">
<div class="carousel-item active">
<img src="slide1.jpg" class="d-block w-100" alt="Slide 1">
<div class="carousel-caption">
<h5>První snímek</h5>
<p>Popis prvního snímku</p>
</div>
</div>
<div class="carousel-item">
<img src="slide2.jpg" class="d-block w-100" alt="Slide 2">
</div>
<div class="carousel-item">
<img src="slide3.jpg" class="d-block w-100" alt="Slide 3">
</div>
</div>
<!-- Ovládací šipky -->
<button class="carousel-control-prev" type="button"
data-bs-target="#carouselExample" data-bs-slide="prev">
<span class="carousel-control-prev-icon"></span>
</button>
<button class="carousel-control-next" type="button"
data-bs-target="#carouselExample" data-bs-slide="next">
<span class="carousel-control-next-icon"></span>
</button>
</div>
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Sledujte automatické přepínání snímků
3. Vyzkoušejte kliknout na šipky (prev/next)
4. Klikněte na indikátory (tečky) pro přímý přechod
5. Prozkoumejte HTML - všimněte si `data-bs-*` atributů
6. Zkuste přidat další snímek (carousel-item)
7. Změňte caption texty
## 💡 Tip pro studenty
### Důležité třídy:
- **carousel slide** - hlavní wrapper
- **carousel-inner** - kontejner pro snímky
- **carousel-item** - jednotlivý snímek
- **carousel-item active** - aktivní (viditelný) snímek
- **d-block w-100** - obrázek na celou šířku
### Data attributes:
```html
<!-- Automatické spuštění -->
data-bs-ride="carousel"
<!-- Přechod na konkrétní snímek -->
data-bs-slide-to="0" <!-- první snímek (indexováno od 0) -->
<!-- Přechod vpřed/vzad -->
data-bs-slide="prev" <!-- předchozí -->
data-bs-slide="next" <!-- další -->
<!-- Interval mezi snímky (v ms) -->
data-bs-interval="5000" <!-- 5 sekund -->
```
### Carousel varianty:
**Bez automatického přepínání:**
```html
<div class="carousel slide"> <!-- bez data-bs-ride -->
```
**Fade efekt místo slide:**
```html
<div class="carousel slide carousel-fade" data-bs-ride="carousel">
```
**Vlastní interval:**
```html
<div class="carousel-item" data-bs-interval="2000">
<!-- tento snímek se zobrazí 2 sekundy -->
</div>
```
### JavaScript API:
```javascript
// Získání carousel instance
var myCarousel = document.querySelector('#myCarousel')
var carousel = new bootstrap.Carousel(myCarousel)
// Ovládání
carousel.next() // další snímek
carousel.prev() // předchozí snímek
carousel.to(2) // přechod na snímek 2
carousel.cycle() // spustit automatické přepínání
carousel.pause() // pozastavit
```
### Responzivní carousel:
```html
<!-- Různé výšky pro různá zařízení -->
<style>
.carousel-item img {
height: 400px;
object-fit: cover;
}
@media (max-width: 768px) {
.carousel-item img {
height: 250px;
}
}
</style>
```
## ⚠️ Důležité poznámky
1. **První carousel-item musí mít třídu `active`**
2. **Všechny data-bs-target musí odpovídat ID carouselu**
3. **Bootstrap.js musí být připojen** - carousel funguje na JavaScriptu
4. **Obrázky by měly mít stejné rozměry** pro hezký vzhled
## 🎯 Praktické využití
- **Hlavní stránka** - hero slider s produkty
- **Galerie** - slideshow fotek
- **Testimonials** - recenze zákazníků
- **Portfolio** - ukázky projektů
## 🔗 Související lekce
- **Předchozí:** 15_bootstrap_components - Bootstrap komponenty
- **Další:** 17_modal - Bootstrap modal
- **Dokumentace:** [Bootstrap Carousel](https://getbootstrap.com/docs/5.3/components/carousel/)

224
17_modal/README.md

@ -0,0 +1,224 @@
# 17 - Bootstrap Modal
## 🎯 Co se naučíte
V této lekci se naučíte vytvářet modální okna (pop-up okna) pomocí Bootstrapu.
## 📚 Témata lekce
- **Modal** - modální okno (overlay)
- **Modal struktura** - header, body, footer
- **Data attributes** - `data-bs-toggle`, `data-bs-target`
- **Modal velikosti** - malé, velké, extra velké
- **Scrollable modal** - pro dlouhý obsah
- **Centered modal** - centrované na obrazovce
- **JavaScript Modal API** - otevírání/zavírání přes JS
- **Modal events** - události (show, hide)
## 📂 Soubory v projektu
- `index.html` - HTML s modal komponentou
- `css/bootstrap.css` - Bootstrap CSS
- `js/bootstrap.js` - Bootstrap JS (DŮLEŽITÝ pro modal!)
## 💻 Základní Modal
```html
<!-- Tlačítko pro otevření modalu -->
<button type="button" class="btn btn-primary"
data-bs-toggle="modal" data-bs-target="#exampleModal">
Otevřít modal
</button>
<!-- Modal struktura -->
<div class="modal fade" id="exampleModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<!-- Header -->
<div class="modal-header">
<h5 class="modal-title">Nadpis modalu</h5>
<button type="button" class="btn-close"
data-bs-dismiss="modal"></button>
</div>
<!-- Body -->
<div class="modal-body">
<p>Obsah modálního okna...</p>
</div>
<!-- Footer -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">Zavřít</button>
<button type="button" class="btn btn-primary">Uložit</button>
</div>
</div>
</div>
</div>
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Klikněte na tlačítko pro otevření modalu
3. Vyzkoušejte zavření pomocí:
- Křížku (×)
- Tlačítka "Zavřít"
- Kliknutí mimo modal
- Klávesy Esc
4. Prozkoumejte HTML strukturu modalu
5. Zkuste změnit velikost modalu
6. Přidejte formulář do modal-body
## 💡 Tip pro studenty
### Data attributes:
**Otevření modalu:**
```html
<button data-bs-toggle="modal" data-bs-target="#myModal">
Otevřít
</button>
```
- **data-bs-toggle="modal"** - zapne modal funkcionalitu
- **data-bs-target="#myModal"** - ID modalu, který se otevře
**Zavření modalu:**
```html
<button data-bs-dismiss="modal">Zavřít</button>
```
### Velikosti modalu:
```html
<!-- Malý modal -->
<div class="modal-dialog modal-sm">
<!-- Normální (výchozí) -->
<div class="modal-dialog">
<!-- Velký -->
<div class="modal-dialog modal-lg">
<!-- Extra velký -->
<div class="modal-dialog modal-xl">
<!-- Celá obrazovka -->
<div class="modal-dialog modal-fullscreen">
```
### Centrovaný modal:
```html
<div class="modal-dialog modal-dialog-centered">
<!-- vertikálně centrovaný -->
</div>
```
### Scrollable modal (dlouhý obsah):
```html
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-body">
<!-- dlouhý obsah zde -->
</div>
</div>
</div>
```
### JavaScript API:
```javascript
// Otevření modalu přes JavaScript
var myModal = new bootstrap.Modal(document.getElementById('myModal'))
myModal.show()
// Zavření
myModal.hide()
// Přepnutí (toggle)
myModal.toggle()
```
### Modal events:
```javascript
var modalEl = document.getElementById('myModal')
// Před otevřením
modalEl.addEventListener('show.bs.modal', function () {
console.log('Modal se otevírá')
})
// Po otevření
modalEl.addEventListener('shown.bs.modal', function () {
console.log('Modal je otevřený')
})
// Před zavřením
modalEl.addEventListener('hide.bs.modal', function () {
console.log('Modal se zavírá')
})
// Po zavření
modalEl.addEventListener('hidden.bs.modal', function () {
console.log('Modal je zavřený')
})
```
## 🎯 Praktické příklady
### Modal s formulářem:
```html
<div class="modal-body">
<form>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email">
</div>
<div class="mb-3">
<label for="password" class="form-label">Heslo</label>
<input type="password" class="form-control" id="password">
</div>
</form>
</div>
```
### Potvrzovací dialog:
```html
<div class="modal-body">
<p>Opravdu chcete smazat tento záznam?</p>
</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal">Ne</button>
<button class="btn btn-danger" onclick="deleteRecord()">Ano, smazat</button>
</div>
```
## 🎨 Praktické využití
- **Přihlášení/Registrace** - formulář v modalu
- **Potvrzení akce** - "Opravdu smazat?"
- **Detaily produktu** - zobrazení více informací
- **Galerie obrázků** - lightbox efekt
- **Video přehrávač** - YouTube/Vimeo embed
- **Notifikace** - důležité zprávy
## ⚠️ Důležité poznámky
1. **Modal musí mít jedinečné ID**
2. **Bootstrap.js musí být připojen** - modal funguje na JavaScriptu
3. **data-bs-target musí odpovídat ID modalu**
4. **Vnořené modaly se nedoporučují** (modal v modalu)
5. **Backdrop** (tmavé pozadí) se dá vypnout: `data-bs-backdrop="false"`
## 🔗 Související lekce
- **Předchozí:** 16_carousel - Bootstrap carousel
- **Související:**
- 15_bootstrap_components - ostatní komponenty
- AI/ai_04_prep_bootstrap - vlastní modal implementace
- **Dokumentace:** [Bootstrap Modal](https://getbootstrap.com/docs/5.3/components/modal/)

181
18_forms/README.md

@ -0,0 +1,181 @@
# 18 - Bootstrap Formuláře a DOM Manipulace
## 🎯 Co se naučíte
V této lekci se naučíte vytvářet dynamické formuláře s Bootstrapem a DOM manipulací.
## 📚 Témata lekce
- **Bootstrap formuláře** - `form-control`, `form-label`, `mb-3`
- **addEventListener** - moderní přístup k event handlingu
- **event.preventDefault()** - zabránění default chování formuláře
- **DOM manipulace** - vytváření elementů pomocí JS
- **createElement()** - vytvoření nového elementu
- **appendChild()** - přidání elementu do DOM
- **Template literals** - backticks pro HTML šablony
- **Bootstrap Cards** - kartičky pro obsah
- **Real-time výpis** - návštěvní kniha
## 📂 Soubory v projektu
- `index.html` - kompletní aplikace s formulářem a výpisem
- `css/bootstrap.css` - Bootstrap CSS
## 💻 Ukázka z lekce
### Formulář s Bootstrap třídami:
```html
<form id="guestbookForm">
<div class="mb-3">
<label for="name" class="form-label">Jméno:</label>
<input type="text" class="form-control" id="name" required>
</div>
<div class="mb-3">
<label for="message" class="form-label">Zpráva:</label>
<textarea class="form-control" id="message" required></textarea>
</div>
<button type="submit" class="btn btn-danger w-100">ODESLAT</button>
</form>
<div id="entries"></div>
```
### JavaScript - Template Literals (rychlejší):
```javascript
form.addEventListener("submit", function(e) {
e.preventDefault();
const name = document.getElementById("name").value;
const message = document.getElementById("message").value;
// Template literal s backticks
const htmldiv = `
<div class="alert alert-info">
<strong>${name}</strong>: ${message}
</div>
`;
entriesDiv.innerHTML += htmldiv;
form.reset();
});
```
### JavaScript - createElement (strukturovanější):
```javascript
form.addEventListener("submit", function(e) {
e.preventDefault();
const name = document.getElementById("name").value;
const message = document.getElementById("message").value;
// Vytvoření elementů
const div = document.createElement("div");
div.className = "alert alert-danger";
const strong = document.createElement("strong");
strong.textContent = name;
const text = document.createElement("span");
text.textContent = ": " + message;
// Složení dohromady
div.appendChild(strong);
div.appendChild(text);
// Vložení do stránky
entriesDiv.appendChild(div);
form.reset();
});
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Vyplňte jméno a zprávu do formuláře
3. Odešlete formulář - zpráva se objeví pod formulářem
4. Přidejte další zprávy - všechny se zobrazí
5. Prozkoumejte JavaScript kód - dvě různé metody
6. Vyzkoušejte Developer Tools (F12) - sledujte DOM změny
## 💡 Tip pro studenty
### addEventListener vs onclick:
```javascript
// ✅ MODERNÍ přístup (doporučený)
form.addEventListener("submit", function(e) {
e.preventDefault();
// ...
});
// ❌ STARŠÍ přístup (méně flexibilní)
<form onsubmit="return handleSubmit()">
```
### event.preventDefault():
```javascript
form.addEventListener("submit", function(e) {
e.preventDefault(); // Zastaví odeslání a reload stránky
// Můžeme zpracovat data vlastním způsobem
});
```
### Template Literals (backticks):
```javascript
// Starý způsob (konkatenace)
const html = "<div>" + name + ": " + message + "</div>";
// ✅ Nový způsob (template literal)
const html = `<div>${name}: ${message}</div>`;
```
- Používá **backticks** (AltGr + ý)
- **${proměnná}** - vložení hodnoty proměnné
- Podporuje **víceřádkové stringy**
### innerHTML vs appendChild:
**innerHTML** - rychlé, ale přepisuje vše:
```javascript
div.innerHTML = `<p>Nový obsah</p>`;
div.innerHTML += `<p>Přidaný obsah</p>`;
```
**appendChild** - přidává element, lepší pro DOM manipulaci:
```javascript
const p = document.createElement("p");
p.textContent = "Nový obsah";
div.appendChild(p);
```
### Bootstrap Form Classes:
```html
<!-- Form group -->
<div class="mb-3"> <!-- margin-bottom: 1rem -->
<label class="form-label">Název</label>
<input class="form-control" type="text">
</div>
<!-- Input velikosti -->
<input class="form-control form-control-sm"> <!-- malý -->
<input class="form-control"> <!-- normální -->
<input class="form-control form-control-lg"> <!-- velký -->
<!-- Full width button -->
<button class="btn btn-primary w-100">Tlačítko</button>
```
## 🎯 Praktické využití
- **Návštěvní kniha** - uživatelé zanechávají vzkazy
- **Chat aplikace** - zprávy v real-time
- **Komentáře** - pod článkem
- **Todo list** - přidávání úkolů
- **Košík** - přidávání produktů
## 🔗 Související lekce
- **Předchozí:**
- 17_modal - Bootstrap modal
- 08_js_form - základy formulářů v JS
- **Další:** 19_todolist - Todo list aplikace
- **Související:** AI/ai_03_form_validation - pokročilá validace formulářů

220
19_todolist/README.md

@ -0,0 +1,220 @@
# 19 - Todo List Aplikace
## 🎯 Co se naučíte
V této lekci se naučíte vytvořit kompletní Todo List aplikaci s přidáváním, odebíráním a označováním úkolů.
## 📚 Témata lekce
- **Todo List aplikace** - praktický projekt
- **Dynamické přidávání položek** do seznamu
- **Odstranění položek** z DOM
- **Toggle stavu** - splněno/nesplněno
- **Local Storage** - ukládání dat v prohlížeči (možná)
- **Event delegation** - efektivní event handling
- **Bootstrap styling** pro moderní UI
- **Textarea** - víceřádkový vstup
## 📂 Soubory v projektu
- `index.html` - HTML s formulářem a seznamem
- `todo.js` - JavaScript pro funkcionalitu
- `css/bootstrap.css` - Bootstrap CSS
## 💻 Ukázka z lekce
### HTML struktura:
```html
<textarea class="form-control velkytext" id="todoitem"
placeholder="Zde napiš úkol"></textarea>
<button class="btn btn-primary w-100 my-3" onclick="additem()">
ZAPSAT
</button>
<ul id="todoList"></ul>
```
### JavaScript - Přidání úkolu:
```javascript
function additem() {
const todoitem = document.getElementById("todoitem").value;
if (todoitem === "") {
alert("Zadej úkol!");
return;
}
const todoList = document.getElementById("todoList");
// Vytvoření <li> elementu
const li = document.createElement("li");
li.className = "todolistitem";
li.innerHTML = `
${todoitem}
<button class="btn btn-danger btn-sm ms-2"
onclick="removeitem(this)">Smazat</button>
<button class="btn btn-success btn-sm ms-1"
onclick="toggleitem(this)">Hotovo</button>
`;
todoList.appendChild(li);
// Vyčištění textarea
document.getElementById("todoitem").value = "";
}
// Odstranění úkolu
function removeitem(button) {
const li = button.parentElement;
li.remove();
}
// Toggle splněno/nesplněno
function toggleitem(button) {
const li = button.parentElement;
li.classList.toggle("text-decoration-line-through");
li.classList.toggle("text-muted");
}
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Napište úkol do textarey
3. Klikněte na "ZAPSAT" - úkol se přidá do seznamu
4. Vyzkoušejte tlačítko "Hotovo" - přeškrtne úkol
5. Klikněte na "Smazat" - odstraní úkol ze seznamu
6. Přidejte více úkolů a vyzkoušejte všechny funkce
7. Prozkoumejte `todo.js` - jak funguje logika
## 💡 Tip pro studenty
### parentElement:
```javascript
function removeitem(button) {
// button = <button> element
// button.parentElement = <li> element (rodič)
const li = button.parentElement;
li.remove();
}
```
### classList.toggle():
```javascript
// Toggle třídy (přidá/odebere)
element.classList.toggle("active");
// Přidá třídu
element.classList.add("active");
// Odebere třídu
element.classList.remove("active");
// Zkontroluje, zda má třídu
element.classList.contains("active"); // true/false
```
### text-decoration-line-through:
```html
<!-- Přeškrtnutý text -->
<p class="text-decoration-line-through">Dokončeno</p>
```
### Validace vstupu:
```javascript
if (todoitem === "" || todoitem.trim() === "") {
alert("Zadej úkol!");
return; // Ukončí funkci
}
```
## 🎯 Rozšíření projektu
### 1. Local Storage (ukládání dat):
```javascript
// Uložení do local storage
function saveTodos() {
const todos = [];
document.querySelectorAll("#todoList li").forEach(li => {
todos.push(li.textContent);
});
localStorage.setItem("todos", JSON.stringify(todos));
}
// Načtení z local storage
function loadTodos() {
const todos = JSON.parse(localStorage.getItem("todos")) || [];
todos.forEach(todo => {
// Přidat do seznamu
});
}
// Volat při načtení stránky
window.onload = loadTodos;
```
### 2. Počítadlo úkolů:
```html
<p>Celkem úkolů: <span id="totalCount">0</span></p>
<p>Dokončeno: <span id="completedCount">0</span></p>
```
```javascript
function updateCounters() {
const total = document.querySelectorAll("#todoList li").length;
const completed = document.querySelectorAll("#todoList li.text-decoration-line-through").length;
document.getElementById("totalCount").textContent = total;
document.getElementById("completedCount").textContent = completed;
}
```
### 3. Priorita úkolů:
```html
<select id="priority" class="form-select">
<option value="low">Nízká</option>
<option value="medium">Střední</option>
<option value="high">Vysoká</option>
</select>
```
```javascript
// Barevné označení podle priority
if (priority === "high") {
li.classList.add("border-start", "border-danger", "border-5");
}
```
### 4. Editace úkolů:
```javascript
function edititem(button) {
const li = button.parentElement;
const newText = prompt("Upravit úkol:", li.firstChild.textContent);
if (newText) {
// Aktualizovat text úkolu
}
}
```
## ⚠️ Důležité poznámky
1. **Validace vstupu** - kontrolujte prázdné hodnoty
2. **trim()** - odstraní mezery na začátku a konci
3. **this** v onclick - odkazuje na button element
4. **remove()** - moderní způsob odstranění elementu
## 🎨 Praktické využití
- **Todo List** - osobní úkoly
- **Nákupní seznam** - položky k nákupu
- **Checklist** - kontrolní seznam
- **Poznámky** - rychlé poznámky
- **Cíle** - tracking cílů
## 🔗 Související lekce
- **Předchozí:** 18_forms - formuláře a DOM manipulace
- **Další:** 20_ajax - AJAX a Fetch API
- **Související:**
- 11_json - práce s JSON (pro localStorage)
- 06_js_html - základy DOM manipulace

228
20_ajax/README.md

@ -0,0 +1,228 @@
# 20 - AJAX a Fetch API
## 🎯 Co se naučíte
V této lekci se naučíte načítat data z externích API pomocí Fetch API.
## 📚 Témata lekce
- **AJAX** - Asynchronous JavaScript and XML
- **Fetch API** - moderní způsob načítání dat
- **Promises** - asynchronní operace
- **async/await** - čistší syntax pro asynchronní kód
- **JSON API** - práce s REST API
- **Pokémon API** - praktická ukázka (pokeapi.co)
- **JSONPlaceholder** - testovací API (jsonplaceholder.typicode.com)
- **Error handling** - ošetření chyb při načítání
## 📂 Soubory v projektu
- `index.html` - rozcestník
- `pokemon.html` - práce s Pokémon API
- `todofetch.html` - práce s Todo API
- JavaScript soubory pro fetch operace
## 💻 Základní Fetch
### Fetch - Promise syntax:
```javascript
// Načtení dat z API
fetch('https://pokeapi.co/api/v2/pokemon/pikachu')
.then(response => response.json()) // Převod na JSON
.then(data => {
console.log(data);
// Práce s daty
document.getElementById("name").textContent = data.name;
})
.catch(error => {
console.error('Chyba:', error);
alert('Nepodařilo se načíst data');
});
```
### Fetch - async/await syntax (modernější):
```javascript
async function loadPokemon() {
try {
const response = await fetch('https://pokeapi.co/api/v2/pokemon/pikachu');
const data = await response.json();
console.log(data);
document.getElementById("name").textContent = data.name;
document.getElementById("image").src = data.sprites.front_default;
} catch (error) {
console.error('Chyba:', error);
alert('Nepodařilo se načíst data');
}
}
// Volání funkce
loadPokemon();
```
## 🚀 Jak s lekcí pracovat
1. Otevřete `index.html` v prohlížeči
2. Klikněte na "Práce s Pokémon API"
3. Sledujte načítání dat z API
4. Otevřete **Console** (F12) - uvidíte API odpovědi
5. Vyzkoušejte "Práce s TodoList API"
6. Prozkoumejte JavaScript kód - jak funguje fetch
7. Zkuste změnit URL API a načíst jiná data
## 💡 Tip pro studenty
### Fetch API kroky:
1. **Zavolat fetch()** s URL
2. **Počkat na response** (.then nebo await)
3. **Převést na JSON** (.json())
4. **Použít data** (zobrazit, zpracovat)
5. **Ošetřit chyby** (.catch nebo try/catch)
### GET request (načtení dat):
```javascript
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
```
### POST request (odeslání dat):
```javascript
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'Nový úkol',
completed: false
})
})
.then(response => response.json())
.then(data => console.log('Vytvořeno:', data))
.catch(error => console.error('Chyba:', error));
```
### Async/Await pattern:
```javascript
async function getData() {
try {
const response = await fetch(url);
// Kontrola, zda je response OK
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
return data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
// Použití
getData()
.then(data => console.log(data))
.catch(error => console.error(error));
```
### Loading indicator:
```javascript
async function loadData() {
// Zobrazit loading
document.getElementById("loading").style.display = "block";
try {
const response = await fetch(url);
const data = await response.json();
// Zpracovat data
displayData(data);
} catch (error) {
console.error(error);
} finally {
// Skrýt loading
document.getElementById("loading").style.display = "none";
}
}
```
## 🎯 Praktické příklady
### Pokémon API:
```javascript
async function loadPokemon(name) {
const url = `https://pokeapi.co/api/v2/pokemon/${name}`;
const response = await fetch(url);
const pokemon = await response.json();
// Zobrazení dat
document.getElementById("pokemonName").textContent = pokemon.name;
document.getElementById("pokemonImage").src = pokemon.sprites.front_default;
document.getElementById("pokemonType").textContent = pokemon.types[0].type.name;
document.getElementById("pokemonWeight").textContent = pokemon.weight;
}
// Volání
loadPokemon("pikachu");
```
### JSONPlaceholder - Todo API:
```javascript
async function loadTodos() {
const response = await fetch('https://jsonplaceholder.typicode.com/todos');
const todos = await response.json();
// Zobrazit prvních 10 todos
const ul = document.getElementById("todoList");
todos.slice(0, 10).forEach(todo => {
const li = document.createElement("li");
li.className = todo.completed ? "completed" : "";
li.textContent = todo.title;
ul.appendChild(li);
});
}
```
## 🌐 Užitečná testovací API
- **JSONPlaceholder**: https://jsonplaceholder.typicode.com/
- Fake REST API pro testování
- Todos, posts, users, comments
- **PokeAPI**: https://pokeapi.co/
- Pokémon data
- Obrázky, statistiky, typy
- **OpenWeather API**: https://openweathermap.org/api
- Počasí (vyžaduje API klíč)
- **Cat Facts API**: https://catfact.ninja/fact
- Náhodné fakty o kočkách
## ⚠️ Důležité poznámky
1. **CORS** - některá API mohou blokovat requesty z prohlížeče
2. **API klíče** - některá API vyžadují registraci a klíč
3. **Rate limiting** - omezení počtu requestů
4. **async funkce** vrací vždy Promise
5. **await** lze použít pouze v async funkci
6. **try/catch** vždy použijte pro error handling
## 🔗 Související lekce
- **Předchozí:**
- 19_todolist - Todo list aplikace
- 11_json - práce s JSON
- **Související:** API integrace v reálných projektech
- **Dokumentace:**
- [Fetch API - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
- [Async/Await - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)

248
AI_extra_material/18_form_validation_bootstrap/ZADANI.md

@ -0,0 +1,248 @@
# Lekce 18: Bootstrap Formuláře a Validace
## 🎯 Cíl lekce
Naučit studenty pracovat s Bootstrap formuláři a validací. **Studenti se s validací formulářů setkávají poprvé!**
## 📝 Osnova lekce
### Část 1: Základní Bootstrap formuláře (20 min)
- Třída `form-control` pro input, textarea
- Třída `form-select` pro select
- Třída `form-check-input` pro checkbox/radio
- `form-label` pro popisky
- `form-text` pro nápovědu
- Spacing pomocí `mb-3` (margin-bottom)
### Část 2: HTML5 validace (15 min)
- Atribut `required` - povinné pole
- `minlength` a `maxlength` - omezení délky
- `min` a `max` pro number input
- `pattern` - regulární výrazy pro formát
- `type="email"`, `type="tel"`, `type="number"`
### Část 3: Bootstrap validační styly (20 min)
- Třídy `is-valid` a `is-invalid`
- `valid-feedback` - zelená zpráva ✅
- `invalid-feedback` - červená zpráva ❌
- Třída `needs-validation` na formuláři
- JavaScript validace s `checkValidity()`
- Třída `was-validated` pro zobrazení feedbacku
### Část 4: Input Groups (10 min)
- `input-group` pro seskupení
- `input-group-text` pro prefix/suffix
- Praktické použití: @ před emailem, +420 před tel., Kč za cenou
### Část 5: Floating Labels (10 min)
- Moderní vzhled formulářů
- `form-floating` wrapper
- Label se "vyplaví" nahoru při focusu
### Část 6: Praktický projekt (40 min)
Studenti vytvoří vlastní kontaktní formulář
## 📁 Soubory v této lekci
### `index.html`
Hlavní soubor s 5 demo sekcemi:
1. ✅ Základní formulář
2. ✅ HTML5 validace
3. ✅ Bootstrap validace s JavaScriptem
4. ✅ Input Groups
5. ✅ Floating Labels
**Použití:** Projděte s studenty všechny sekce postupně. Nechte je vyzkoušet formuláře!
### `template.html`
Startovací šablona pro studenty s:
- ✅ Základní HTML strukturou
- ✅ Jedním ukázkovým polem
- ✅ Připraveným JavaScriptem
- ✅ Nápovědou v sidebaru
**Použití:** Studenti mohou tuto šablonu použít jako základ pro svůj projekt.
### `reseni_kontaktni_formular.html`
Kompletní řešení projektu obsahující:
- ✅ Všechna požadovaná pole
- ✅ Floating labels
- ✅ Input group u telefonu (+420)
- ✅ Validaci všech polí
- ✅ Success alert po odeslání
- ✅ BONUS funkce:
- Real-time validace telefonu
- Počítadlo znaků u zprávy
- Scroll k chybám
- Console.log výpis dat
**Použití:** Ukažte studentům po dokončení jejich projektů. Projděte zejména JavaScript část!
## 🎯 Projekt pro studenty
### Zadání: Kontaktní formulář
Vytvořte plně funkční kontaktní formulář s těmito požadavky:
#### Povinná pole:
1. **Jméno** - textový input, required
2. **Email** - emailový input, required, správný formát
3. **Předmět** - select s možnostmi, required
4. **Zpráva** - textarea, required, min. 10 znaků
#### Nepovinné pole:
5. **Telefon** - tel input s pattern `[0-9]{9}` (české číslo)
#### Další požadavky:
- ✅ Checkbox "Souhlasím se zpracováním údajů" (required)
- ✅ Použít **Floating labels** pro všechna pole
- ✅ **Input group** u telefonu s textem "+420"
- ✅ Zobrazit **Success Alert** po úspěšném odeslání
- ✅ Validovat pomocí JavaScriptu
- ✅ Resetovat formulář po 3-4 sekundách
#### Bonus úkoly:
- Real-time validace během psaní
- Počítadlo znaků u zprávy
- Scroll k prvnímu chybnému poli
- Vypsat data do console.log
### Hodnocení (20 bodů):
- **HTML struktura (5b)**
- Správná struktura formuláře (2b)
- Všechna pole implementována (2b)
- Správné atributy (required, pattern, type) (1b)
- **Bootstrap styly (5b)**
- Floating labels použity správně (2b)
- Input group u telefonu (1b)
- Správné Bootstrap třídy (form-control, atd.) (2b)
- **Validace (6b)**
- HTML5 validace správně nastavena (2b)
- JavaScript validace funguje (3b)
- Invalid/valid feedback zprávy (1b)
- **Funkčnost (4b)**
- Formulář se validuje před odesláním (2b)
- Success alert se zobrazí (1b)
- Formulář se resetuje (1b)
**Bonusové body (+5b max):**
- Real-time validace (+2b)
- Počítadlo znaků (+1b)
- Scroll k chybám (+1b)
- Console.log výpis (+1b)
## 💡 Tipy pro učitele
### Při výuce:
1. **Začněte prakticky** - Nechte studenty rovnou zkoušet formuláře v `index.html`
2. **Vysvětlete rozdíl** mezi:
- HTML5 validací (vestavěná v prohlížeči)
- Bootstrap validací (vizuální feedback)
- JavaScript validací (programová kontrola)
3. **Ukažte DevTools** - Zapněte Console a ukazujte jak funguje `checkValidity()`
4. **Pattern (RegEx)** - Nebojte se! Ukažte jen jednoduché příklady:
- `[0-9]{9}` = přesně 9 číslic
- `[0-9]{5}` = PSČ (5 číslic)
- Odkažte na regex101.com pro testování
5. **Event preventDefault** - Vysvětlete proč musíme zastavit defaultní submit
### Časté chyby studentů:
❌ **Zapomenou `novalidate` na formuláři**
- Výsledek: Prohlížeč zobrazí vlastní validaci místo Bootstrap stylů
- Řešení: `<form class="needs-validation" novalidate>`
❌ **Zapomenou `event.preventDefault()`**
- Výsledek: Formulář se odešle a stránka se obnoví
- Řešení: První řádek v event listeneru musí být `event.preventDefault()`
❌ **Nepoužijí `was-validated` třídu**
- Výsledek: Feedback zprávy se nezobrazí
- Řešení: Po submitu přidat `form.classList.add('was-validated')`
❌ **Dají `is-valid` přímo do HTML**
- Výsledek: Pole vypadá validní už před vyplněním
- Řešení: Třídy `is-valid`/`is-invalid` se přidávají JavaScriptem, ne v HTML
❌ **Špatný selector pro feedback**
- Výsledek: Zprávy se nezobrazí u správného pole
- Řešení: `invalid-feedback` musí být sourozenec inputu (na stejné úrovni)
## 📊 Postup výuky (90 min)
### Fáze 1: Představení (10 min)
- Ukažte hotový `reseni_kontaktni_formular.html`
- Vyplňte správně i špatně - ukažte rozdíl
- Motivujte studenty: "Tohle dnes vytvoříte!"
### Fáze 2: Průchod příklady (30 min)
- Otevřete `index.html`
- Projděte sekci po sekci
- Nechte studenty zkoušet každou sekci
- Vysvětlete JavaScript část u sekce 3
### Fáze 3: Template a zadání (10 min)
- Ukažte `template.html`
- Projděte zadání z `index.html` (sekce "Projekt pro vás")
- Zodpovězte dotazy
### Fáze 4: Samostatná práce (35 min)
- Studenti pracují na projektu
- Procházejte mezi nimi
- Pomáhejte s dotazy
### Fáze 5: Prezentace řešení (5 min)
- Otevřete `reseni_kontaktni_formular.html`
- Projděte kód
- Ukažte bonus funkce
## 🔗 Navazující lekce
Po této lekci můžete pokračovat:
- **19 - Alerts & Toasts** (notifikace uživateli)
- **20 - Navbar & Dropdowns** (navigace)
- **Závěrečný projekt** kombinující formuláře s jinými komponenty
## 📚 Užitečné odkazy pro studenty
- [Bootstrap Forms dokumentace](https://getbootstrap.com/docs/5.3/forms/overview/)
- [Bootstrap Validation](https://getbootstrap.com/docs/5.3/forms/validation/)
- [HTML5 Input types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)
- [RegEx tester](https://regex101.com/)
## ✅ Co by studenti měli umět po této lekci
Po absolvování lekce by studenti měli být schopni:
✅ Vytvořit Bootstrap formulář se správnými třídami
✅ Použít HTML5 validační atributy (required, pattern, minlength)
✅ Implementovat JavaScript validaci pomocí `checkValidity()`
✅ Zobrazit validační feedback (zelený/červený)
✅ Vytvořit Input Groups s prefix/suffix
✅ Použít Floating Labels
✅ Zastavit defaultní odeslání formuláře
✅ Zobrazit Alert po úspěšném odeslání
✅ Resetovat formulář po odeslání
**Bonusové dovednosti:**
- Real-time validace
- Počítadlo znaků
- Scroll k chybám
- Práce s console.log
---
Vytvořeno: 2. prosince 2025
Předmět: Webové Technologie (WTL)
Cílová skupina: 3. ročník IT
**Hodně štěstí při výuce! 🚀**

12048
AI_extra_material/18_form_validation_bootstrap/css/bootstrap.css

File diff suppressed because it is too large

6
AI_extra_material/18_form_validation_bootstrap/css/bootstrap.min.css

File diff suppressed because one or more lines are too long

429
AI_extra_material/18_form_validation_bootstrap/index.html

@ -0,0 +1,429 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bootstrap Forms & Validace</title>
<link rel="stylesheet" href="css/bootstrap.css">
<style>
.demo-section {
margin: 40px 0;
padding: 30px;
border: 2px solid #dee2e6;
border-radius: 10px;
background-color: #f8f9fa;
}
.demo-title {
color: #0d6efd;
margin-bottom: 20px;
}
</style>
</head>
<body class="d-flex flex-column min-vh-100">
<!-- Header -->
<div class="container">
<header class="d-flex flex-wrap justify-content-center py-3 mb-3 border-bottom">
<a href="#" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none fs-4">
Bootstrap Forms & Validace
</a>
<ul class="nav nav-pills">
<li class="nav-item"><a href="#zaklad" class="nav-link">Základy</a></li>
<li class="nav-item"><a href="#html-validace" class="nav-link">HTML validace</a></li>
<li class="nav-item"><a href="#bootstrap-validace" class="nav-link">Bootstrap validace</a></li>
<li class="nav-item"><a href="#projekt" class="nav-link active">Projekt</a></li>
</ul>
</header>
</div>
<!-- MAIN -->
<main class="container">
<h1 class="display-4 mb-4">Lekce 18: Formuláře a Validace</h1>
<!-- SEKCE 1: Základní formulář -->
<div class="demo-section" id="zaklad">
<h2 class="demo-title">1️⃣ Základní Bootstrap Formulář</h2>
<p class="lead">Bootstrap poskytuje krásné styly pro formuláře pomocí třídy <code>form-control</code></p>
<form>
<!-- Textový input -->
<div class="mb-3">
<label for="jmeno" class="form-label">Jméno:</label>
<input type="text" class="form-control" id="jmeno" placeholder="Zadejte jméno">
</div>
<!-- Email input -->
<div class="mb-3">
<label for="email" class="form-label">Email:</label>
<input type="email" class="form-control" id="email" placeholder="vas@email.cz">
<div class="form-text">Zadejte platnou emailovou adresu</div>
</div>
<!-- Password -->
<div class="mb-3">
<label for="heslo" class="form-label">Heslo:</label>
<input type="password" class="form-control" id="heslo">
</div>
<!-- Textarea -->
<div class="mb-3">
<label for="zprava" class="form-label">Zpráva:</label>
<textarea class="form-control" id="zprava" rows="3"></textarea>
</div>
<!-- Select -->
<div class="mb-3">
<label for="zeme" class="form-label">Země:</label>
<select class="form-select" id="zeme">
<option selected>Vyberte zemi...</option>
<option value="cz">Česká republika</option>
<option value="sk">Slovensko</option>
<option value="pl">Polsko</option>
</select>
</div>
<!-- Checkbox -->
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="souhlas">
<label class="form-check-label" for="souhlas">
Souhlasím s podmínkami
</label>
</div>
<button type="submit" class="btn btn-primary">Odeslat</button>
</form>
</div>
<!-- SEKCE 2: HTML5 validace -->
<div class="demo-section" id="html-validace">
<h2 class="demo-title">2️⃣ HTML5 Validace (zabudovaná v prohlížeči)</h2>
<p class="lead">Pomocí HTML atributů <code>required</code>, <code>minlength</code>, <code>maxlength</code>, <code>pattern</code></p>
<div class="alert alert-info">
<strong>💡 Tip:</strong> Zkuste odeslat formulář bez vyplnění - prohlížeč vás upozorní!
</div>
<form>
<!-- Required pole -->
<div class="mb-3">
<label for="jmeno2" class="form-label">Jméno (povinné):</label>
<input type="text" class="form-control" id="jmeno2" required>
</div>
<!-- Email s required -->
<div class="mb-3">
<label for="email2" class="form-label">Email (povinný):</label>
<input type="email" class="form-control" id="email2" required>
</div>
<!-- Min a max length -->
<div class="mb-3">
<label for="username" class="form-label">Uživatelské jméno (min 3, max 15 znaků):</label>
<input type="text" class="form-control" id="username"
minlength="3" maxlength="15" required>
</div>
<!-- Pattern (regulární výraz) -->
<div class="mb-3">
<label for="telefon" class="form-label">Telefon (formát: 123456789):</label>
<input type="tel" class="form-control" id="telefon"
pattern="[0-9]{9}"
placeholder="123456789"
required>
</div>
<!-- Number s min/max -->
<div class="mb-3">
<label for="vek" class="form-label">Věk (15-120):</label>
<input type="number" class="form-control" id="vek"
min="15" max="120" required>
</div>
<button type="submit" class="btn btn-success">Odeslat formulář</button>
</form>
</div>
<!-- SEKCE 3: Bootstrap validace s vizuálním feedbackem -->
<div class="demo-section" id="bootstrap-validace">
<h2 class="demo-title">3️⃣ Bootstrap Validace (s vizuálním feedbackem)</h2>
<p class="lead">Bootstrap třídy: <code>is-valid</code> (zelená), <code>is-invalid</code> (červená)</p>
<!-- Příklad: správně vyplněné pole -->
<h4>✅ Správně vyplněné pole:</h4>
<div class="mb-3">
<label for="validEmail" class="form-label">Email:</label>
<input type="email" class="form-control is-valid" id="validEmail" value="uzivatel@email.cz">
<div class="valid-feedback">
Vypadá to dobře!
</div>
</div>
<!-- Příklad: špatně vyplněné pole -->
<h4>❌ Špatně vyplněné pole:</h4>
<div class="mb-3">
<label for="invalidEmail" class="form-label">Email:</label>
<input type="email" class="form-control is-invalid" id="invalidEmail" value="spatnyemail">
<div class="invalid-feedback">
Zadejte prosím platnou emailovou adresu!
</div>
</div>
<hr class="my-5">
<!-- Komplexní formulář s Bootstrap validací -->
<h3>📝 Kompletní registrační formulář s validací</h3>
<div class="alert alert-warning">
<strong>⚠️ Pozor:</strong> Tento formulář používá JavaScript pro validaci. Klikněte na "Registrovat" a uvidíte validaci v akci!
</div>
<form id="registrationForm" class="needs-validation" novalidate>
<div class="row">
<div class="col-md-6 mb-3">
<label for="regJmeno" class="form-label">Jméno *</label>
<input type="text" class="form-control" id="regJmeno" required>
<div class="invalid-feedback">
Vyplňte prosím jméno.
</div>
</div>
<div class="col-md-6 mb-3">
<label for="regPrijmeni" class="form-label">Příjmení *</label>
<input type="text" class="form-control" id="regPrijmeni" required>
<div class="invalid-feedback">
Vyplňte prosím příjmení.
</div>
</div>
</div>
<div class="mb-3">
<label for="regEmail" class="form-label">Email *</label>
<input type="email" class="form-control" id="regEmail" required>
<div class="invalid-feedback">
Zadejte platnou emailovou adresu.
</div>
</div>
<div class="mb-3">
<label for="regUsername" class="form-label">Uživatelské jméno *</label>
<input type="text" class="form-control" id="regUsername"
minlength="3" maxlength="15" required>
<div class="invalid-feedback">
Uživatelské jméno musí mít 3-15 znaků.
</div>
</div>
<div class="mb-3">
<label for="regHeslo" class="form-label">Heslo *</label>
<input type="password" class="form-control" id="regHeslo"
minlength="6" required>
<div class="invalid-feedback">
Heslo musí mít alespoň 6 znaků.
</div>
</div>
<div class="mb-3">
<label for="regHeslo2" class="form-label">Heslo znovu *</label>
<input type="password" class="form-control" id="regHeslo2" required>
<div class="invalid-feedback">
Hesla se musí shodovat.
</div>
</div>
<div class="mb-3">
<label for="regVek" class="form-label">Věk *</label>
<input type="number" class="form-control" id="regVek"
min="15" max="120" required>
<div class="invalid-feedback">
Věk musí být mezi 15 a 120 lety.
</div>
</div>
<div class="mb-3">
<label for="regZeme" class="form-label">Země *</label>
<select class="form-select" id="regZeme" required>
<option value="">Vyberte...</option>
<option value="cz">Česká republika</option>
<option value="sk">Slovensko</option>
<option value="pl">Polsko</option>
<option value="at">Rakousko</option>
</select>
<div class="invalid-feedback">
Vyberte prosím zemi.
</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="regSouhlas" required>
<label class="form-check-label" for="regSouhlas">
Souhlasím s podmínkami *
</label>
<div class="invalid-feedback">
Musíte souhlasit s podmínkami.
</div>
</div>
<button type="submit" class="btn btn-primary btn-lg">Registrovat</button>
</form>
<div id="successMessage" class="alert alert-success mt-4" style="display: none;">
<h4>✅ Registrace úspěšná!</h4>
<p>Všechna pole byla vyplněna správně.</p>
</div>
</div>
<!-- SEKCE 4: Input Groups -->
<div class="demo-section">
<h2 class="demo-title">4️⃣ Input Groups (pole s ikonami/textem)</h2>
<p class="lead">Přidání textu nebo symbolů před/za input pole</p>
<div class="mb-3">
<label for="username3" class="form-label">Uživatelské jméno:</label>
<div class="input-group">
<span class="input-group-text">@</span>
<input type="text" class="form-control" id="username3" placeholder="uzivatel">
</div>
</div>
<div class="mb-3">
<label for="website" class="form-label">Webová stránka:</label>
<div class="input-group">
<span class="input-group-text">https://</span>
<input type="text" class="form-control" id="website" placeholder="www.example.com">
</div>
</div>
<div class="mb-3">
<label for="cena" class="form-label">Cena:</label>
<div class="input-group">
<input type="number" class="form-control" id="cena" placeholder="0">
<span class="input-group-text"></span>
</div>
</div>
<div class="mb-3">
<label for="search" class="form-label">Vyhledávání:</label>
<div class="input-group">
<input type="text" class="form-control" id="search" placeholder="Hledat...">
<button class="btn btn-outline-secondary" type="button">🔍</button>
</div>
</div>
</div>
<!-- SEKCE 5: Floating Labels -->
<div class="demo-section">
<h2 class="demo-title">5️⃣ Floating Labels (moderní vzhled)</h2>
<p class="lead">Label se zobrazí uvnitř inputu a "vyplave" nahoru po kliknutí</p>
<div class="form-floating mb-3">
<input type="text" class="form-control" id="floatingJmeno" placeholder="Jméno">
<label for="floatingJmeno">Jméno</label>
</div>
<div class="form-floating mb-3">
<input type="email" class="form-control" id="floatingEmail" placeholder="name@example.com">
<label for="floatingEmail">Email</label>
</div>
<div class="form-floating mb-3">
<select class="form-select" id="floatingSelect">
<option selected>Vyberte...</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<label for="floatingSelect">Výběr</label>
</div>
<div class="form-floating mb-3">
<textarea class="form-control" placeholder="Zpráva" id="floatingTextarea" style="height: 100px"></textarea>
<label for="floatingTextarea">Zpráva</label>
</div>
</div>
<!-- PROJEKT PRO STUDENTY -->
<div class="demo-section bg-warning bg-opacity-10" id="projekt">
<h2 class="demo-title text-danger">🎯 PROJEKT PRO VÁS: Kontaktní formulář</h2>
<div class="alert alert-danger">
<h4>📝 Zadání:</h4>
<p>Vytvořte vlastní kontaktní formulář s těmito požadavky:</p>
<ol>
<li><strong>Pole:</strong> Jméno, Email, Telefon, Předmět, Zpráva</li>
<li><strong>Validace:</strong> Všechna pole povinná (kromě Telefon)</li>
<li><strong>Telefon:</strong> Pattern pro české číslo (9 číslic)</li>
<li><strong>Email:</strong> Správný email formát</li>
<li><strong>Zpráva:</strong> Minimálně 10 znaků</li>
<li><strong>Vzhled:</strong> Použijte Floating labels</li>
<li><strong>Bonus:</strong> Přidejte Input group k telefonu (+420)</li>
<li><strong>Submit:</strong> Při úspěšném odeslání zobrazte Alert</li>
</ol>
<p class="mb-0"><strong>Vytvořte nový soubor:</strong> <code>muj_formular.html</code></p>
</div>
</div>
</main>
<!-- Footer -->
<footer class="footer mt-auto py-3 bg-light">
<div class="container text-center">
<span class="text-muted">Bootstrap Forms & Validace | WTL 2025</span>
</div>
</footer>
<!-- JAVASCRIPT pro validaci -->
<script src="js/bootstrap.bundle.js"></script>
<script>
// ===== VALIDACE REGISTRAČNÍHO FORMULÁŘE =====
// Najdeme formulář
const form = document.getElementById('registrationForm');
const successMessage = document.getElementById('successMessage');
// Přidáme event listener na submit
form.addEventListener('submit', function(event) {
// Zastavíme defaultní odeslání formuláře
event.preventDefault();
event.stopPropagation();
// Speciální validace: hesla se musí shodovat
const heslo = document.getElementById('regHeslo');
const heslo2 = document.getElementById('regHeslo2');
if (heslo.value !== heslo2.value) {
heslo2.setCustomValidity('Hesla se neshodují');
} else {
heslo2.setCustomValidity('');
}
// Zkontrolujeme validitu formuláře
if (form.checkValidity()) {
// Formulář je validní - zobrazíme success zprávu
form.classList.add('was-validated');
successMessage.style.display = 'block';
// Scrollujeme ke zprávě
successMessage.scrollIntoView({ behavior: 'smooth' });
// Resetujeme formulář po 3 sekundách
setTimeout(function() {
form.reset();
form.classList.remove('was-validated');
successMessage.style.display = 'none';
}, 3000);
} else {
// Formulář není validní - zobrazíme chyby
form.classList.add('was-validated');
successMessage.style.display = 'none';
}
});
// Real-time validace hesel
document.getElementById('regHeslo2').addEventListener('input', function() {
const heslo = document.getElementById('regHeslo');
const heslo2 = this;
if (heslo.value !== heslo2.value) {
heslo2.setCustomValidity('Hesla se neshodují');
} else {
heslo2.setCustomValidity('');
}
});
</script>
</body>
</html>

6312
AI_extra_material/18_form_validation_bootstrap/js/bootstrap.bundle.js

File diff suppressed because it is too large

7
AI_extra_material/18_form_validation_bootstrap/js/bootstrap.bundle.min.js

File diff suppressed because one or more lines are too long

280
AI_extra_material/18_form_validation_bootstrap/reseni_kontaktni_formular.html

@ -0,0 +1,280 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kontaktní Formulář - Řešení</title>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body class="d-flex flex-column min-vh-100">
<!-- Header -->
<div class="container">
<header class="d-flex flex-wrap justify-content-center py-3 mb-3 border-bottom">
<a href="#" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none fs-4">
Kontaktní Formulář
</a>
<ul class="nav nav-pills">
<li class="nav-item"><a href="index.html" class="nav-link">Zpět na příklady</a></li>
<li class="nav-item"><a href="template.html" class="nav-link">Šablona</a></li>
</ul>
</header>
</div>
<!-- MAIN -->
<main class="container">
<div class="row justify-content-center">
<div class="col-lg-8">
<h1 class="display-5 mb-2">📧 Kontaktujte nás</h1>
<p class="text-muted mb-4">Vyplňte formulář níže a ozveme se vám co nejdříve.</p>
<!-- Kontaktní formulář -->
<form id="contactForm" class="needs-validation" novalidate>
<!-- Jméno - Floating label -->
<div class="form-floating mb-3">
<input type="text"
class="form-control"
id="jmeno"
placeholder="Jméno"
required>
<label for="jmeno">Jméno *</label>
<div class="invalid-feedback">
Prosím vyplňte vaše jméno.
</div>
</div>
<!-- Email - Floating label -->
<div class="form-floating mb-3">
<input type="email"
class="form-control"
id="email"
placeholder="Email"
required>
<label for="email">Email *</label>
<div class="invalid-feedback">
Prosím zadejte platnou emailovou adresu.
</div>
</div>
<!-- Telefon - Input group s +420 a pattern pro 9 číslic -->
<div class="mb-3">
<label for="telefon" class="form-label">Telefon (nepovinné)</label>
<div class="input-group">
<span class="input-group-text">+420</span>
<input type="tel"
class="form-control"
id="telefon"
placeholder="123456789"
pattern="[0-9]{9}">
<div class="invalid-feedback">
Zadejte telefonní číslo ve formátu 123456789 (9 číslic).
</div>
</div>
<div class="form-text">Formát: 9 číslic bez mezer (např. 777123456)</div>
</div>
<!-- Předmět - Floating select -->
<div class="form-floating mb-3">
<select class="form-select" id="predmet" required>
<option value="">Vyberte předmět...</option>
<option value="dotaz">Obecný dotaz</option>
<option value="podpora">Technická podpora</option>
<option value="objednavka">Objednávka</option>
<option value="reklamace">Reklamace</option>
<option value="jine">Jiné</option>
</select>
<label for="predmet">Předmět *</label>
<div class="invalid-feedback">
Vyberte prosím předmět zprávy.
</div>
</div>
<!-- Zpráva - Floating textarea s minlength 10 -->
<div class="form-floating mb-3">
<textarea class="form-control"
id="zprava"
placeholder="Zpráva"
style="height: 150px"
minlength="10"
required></textarea>
<label for="zprava">Zpráva * (min. 10 znaků)</label>
<div class="invalid-feedback">
Zpráva musí obsahovat alespoň 10 znaků.
</div>
</div>
<!-- GDPR souhlas -->
<div class="mb-4 form-check">
<input type="checkbox"
class="form-check-input"
id="souhlas"
required>
<label class="form-check-label" for="souhlas">
Souhlasím se zpracováním osobních údajů *
</label>
<div class="invalid-feedback">
Musíte souhlasit se zpracováním osobních údajů.
</div>
</div>
<!-- Submit button -->
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary btn-lg">
📨 Odeslat zprávu
</button>
</div>
<p class="text-muted mt-3 small">* = povinné pole</p>
</form>
<!-- Success Alert (skrytý, zobrazí se po úspěšném odeslání) -->
<div id="successAlert" class="alert alert-success alert-dismissible fade show mt-4" style="display: none;">
<h4 class="alert-heading">✅ Zpráva byla odeslána!</h4>
<p>Děkujeme za váš kontakt. Ozveme se vám co nejdříve.</p>
<hr>
<p class="mb-0">Obvykle odpovídáme do 24 hodin.</p>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<!-- Info sekce -->
<div class="card mt-5 bg-light">
<div class="card-body">
<h5 class="card-title">📞 Další kontaktní možnosti</h5>
<ul class="list-unstyled mb-0">
<li>📧 Email: info@example.cz</li>
<li>☎️ Telefon: +420 123 456 789</li>
<li>🏢 Adresa: Praha 1, Václavské náměstí 1</li>
</ul>
</div>
</div>
</div>
</div>
</main>
<!-- Footer -->
<footer class="footer mt-auto py-3 bg-light">
<div class="container text-center">
<span class="text-muted">Kontaktní Formulář - Řešení | WTL 2025</span>
</div>
</footer>
<script src="js/bootstrap.bundle.js"></script>
<script>
// ===== JAVASCRIPT VALIDACE =====
// 1. Najdeme formulář a success alert
const contactForm = document.getElementById('contactForm');
const successAlert = document.getElementById('successAlert');
// 2. Přidáme event listener na odeslání formuláře
contactForm.addEventListener('submit', function(event) {
// Zastavíme defaultní odeslání formuláře
event.preventDefault();
event.stopPropagation();
// 3. Zkontrolujeme validitu formuláře
if (contactForm.checkValidity()) {
// ✅ Formulář je validní
// Přidáme třídu pro zobrazení validních polí
contactForm.classList.add('was-validated');
// Zobrazíme success zprávu
successAlert.style.display = 'block';
// Scrollujeme k success zprávě
successAlert.scrollIntoView({ behavior: 'smooth', block: 'center' });
// BONUS: Vypíšeme data z formuláře do console
console.log('=== DATA Z FORMULÁŘE ===');
console.log('Jméno:', document.getElementById('jmeno').value);
console.log('Email:', document.getElementById('email').value);
console.log('Telefon:', document.getElementById('telefon').value || 'nevyplněno');
console.log('Předmět:', document.getElementById('predmet').value);
console.log('Zpráva:', document.getElementById('zprava').value);
console.log('Souhlas GDPR:', document.getElementById('souhlas').checked);
// Resetujeme formulář po 4 sekundách
setTimeout(function() {
contactForm.reset();
contactForm.classList.remove('was-validated');
successAlert.style.display = 'none';
}, 4000);
} else {
// ❌ Formulář není validní
// Přidáme třídu pro zobrazení chyb
contactForm.classList.add('was-validated');
// Skryjeme success zprávu (kdyby byla zobrazená)
successAlert.style.display = 'none';
// Najdeme první invalidní pole a scrollujeme k němu
const firstInvalid = contactForm.querySelector(':invalid');
if (firstInvalid) {
firstInvalid.focus();
firstInvalid.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
}
});
// ===== BONUS: Real-time validace pro telefon =====
// Zobrazíme feedback už při psaní (ne až po submitu)
const telefonInput = document.getElementById('telefon');
telefonInput.addEventListener('input', function() {
// Pokud je pole prázdné, je to OK (není required)
if (this.value === '') {
this.classList.remove('is-invalid');
this.classList.remove('is-valid');
return;
}
// Zkontrolujeme pattern (9 číslic)
const pattern = /^[0-9]{9}$/;
if (pattern.test(this.value)) {
this.classList.remove('is-invalid');
this.classList.add('is-valid');
} else {
this.classList.remove('is-valid');
this.classList.add('is-invalid');
}
});
// ===== BONUS: Počítadlo znaků u zprávy =====
const zpravaInput = document.getElementById('zprava');
// Vytvoříme element pro zobrazení počtu znaků
const counterDiv = document.createElement('div');
counterDiv.className = 'form-text';
counterDiv.id = 'zpravaCounter';
zpravaInput.parentElement.appendChild(counterDiv);
// Funkce pro update počítadla
function updateCounter() {
const length = zpravaInput.value.length;
const min = 10;
if (length === 0) {
counterDiv.textContent = `Napište zprávu (min. ${min} znaků)`;
counterDiv.className = 'form-text';
} else if (length < min) {
counterDiv.textContent = `${length}/${min} znaků - ještě ${min - length} znaků`;
counterDiv.className = 'form-text text-danger';
} else {
counterDiv.textContent = `${length} znaků ✓`;
counterDiv.className = 'form-text text-success';
}
}
// Zavoláme hned na začátku
updateCounter();
// A při každé změně
zpravaInput.addEventListener('input', updateCounter);
</script>
</body>
</html>

128
AI_extra_material/18_form_validation_bootstrap/template.html

@ -0,0 +1,128 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bootstrap Formulář - Šablona</title>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body class="d-flex flex-column min-vh-100">
<!-- Header -->
<div class="container">
<header class="d-flex flex-wrap justify-content-center py-3 mb-3 border-bottom">
<a href="#" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none fs-4">
Můj Formulář
</a>
<ul class="nav nav-pills">
<li class="nav-item"><a href="index.html" class="nav-link">Zpět na příklady</a></li>
</ul>
</header>
</div>
<!-- MAIN -->
<main class="container">
<h1 class="display-4 mb-4">🚀 Startovací šablona pro váš projekt</h1>
<div class="row">
<div class="col-md-8">
<!-- TODO: Zde vytvořte svůj formulář -->
<form id="myForm" class="needs-validation" novalidate>
<!-- Příklad jednoho pole - můžete použít jako vzor -->
<div class="mb-3">
<label for="exampleInput" class="form-label">Ukázkové pole:</label>
<input type="text" class="form-control" id="exampleInput" required>
<div class="invalid-feedback">
Toto pole je povinné.
</div>
</div>
<!-- TODO: Přidejte další pole podle zadání -->
<button type="submit" class="btn btn-primary">Odeslat</button>
</form>
<!-- Success zpráva -->
<div id="successAlert" class="alert alert-success mt-4" style="display: none;">
<h4>✅ Formulář odeslán!</h4>
<p>Všechna pole byla vyplněna správně.</p>
</div>
</div>
<div class="col-md-4">
<!-- Nápověda -->
<div class="card bg-light">
<div class="card-body">
<h5 class="card-title">💡 Nápověda</h5>
<h6>Bootstrap třídy:</h6>
<ul class="small">
<li><code>form-control</code> - pro input, textarea</li>
<li><code>form-select</code> - pro select</li>
<li><code>form-label</code> - pro label</li>
<li><code>form-check-input</code> - pro checkbox/radio</li>
<li><code>invalid-feedback</code> - chybová zpráva</li>
<li><code>valid-feedback</code> - úspěšná zpráva</li>
</ul>
<h6 class="mt-3">HTML atributy:</h6>
<ul class="small">
<li><code>required</code> - povinné pole</li>
<li><code>minlength="X"</code> - min počet znaků</li>
<li><code>maxlength="X"</code> - max počet znaků</li>
<li><code>pattern="..."</code> - regex vzor</li>
<li><code>min="X"</code> - minimální hodnota</li>
<li><code>max="X"</code> - maximální hodnota</li>
</ul>
<h6 class="mt-3">Užitečné vzory (pattern):</h6>
<ul class="small">
<li>Tel.: <code>[0-9]{9}</code></li>
<li>PSČ: <code>[0-9]{5}</code></li>
</ul>
</div>
</div>
</div>
</div>
</main>
<!-- Footer -->
<footer class="footer mt-auto py-3 bg-light">
<div class="container text-center">
<span class="text-muted">Vytvořil/a: [VAŠE JMÉNO] | WTL 2025</span>
</div>
</footer>
<script src="js/bootstrap.bundle.js"></script>
<script>
// TODO: Zde přidejte JavaScript pro validaci
const form = document.getElementById('myForm');
const successAlert = document.getElementById('successAlert');
form.addEventListener('submit', function(event) {
event.preventDefault();
event.stopPropagation();
// TODO: Přidejte vlastní validaci (např. porovnání hesel)
if (form.checkValidity()) {
// Formulář je validní
form.classList.add('was-validated');
successAlert.style.display = 'block';
// Resetovat formulář po 3 sekundách
setTimeout(function() {
form.reset();
form.classList.remove('was-validated');
successAlert.style.display = 'none';
}, 3000);
} else {
// Formulář není validní
form.classList.add('was-validated');
successAlert.style.display = 'none';
}
});
</script>
</body>
</html>

208
AI_extra_material/18a_form_xss_demo/RYCHLY_NAVOD.md

@ -0,0 +1,208 @@
# Rychlý návod - XSS Demo (Zjednodušená verze)
## 📁 Jednoduché soubory pro rychlou demonstraci:
### ⚠️ `zranitelna_jednoducha.html` - NEBEZPEČNÁ
- Minimální kód
- Používá `innerHTML` - lze hacknout!
- Útoky připravené v pravém sloupci
### ✅ `bezpecna_jednoducha.html` - BEZPEČNÁ
- Minimální kód
- Používá `textContent` - nelze hacknout!
- Zobrazí XSS útoky jako text
---
## 🎯 Jak demonstrovat (5 minut):
### 1. Otevřete `zranitelna_jednoducha.html`
### 2. Zkopírujte tento útok do pole "Zpráva":
```html
<img src=x onerror="alert('HACKNUTÝ!')">
```
**POZOR:** Nepoužívejte `<script>` - prohlížeč ho zablokuje! Používejte event handlery!
### 3. Klikněte "Přidat záznam"
- **💥 Alert se zobrazí! = ÚTOK USPĚL!**
### 4. Otevřete `bezpecna_jednoducha.html`
### 5. Zkuste stejný útok
- ✅ **Zobrazí se jako text, nespustí se!**
---
## 💡 Další fungující útoky k vyzkoušení:
```html
<!-- Změna pozadí na červenou -->
<img src=x onerror="document.body.style.background='red'">
<!-- Velký červený nápis -->
<h1 style="color:red; font-size:50px">HACKED!</h1>
<!-- SVG útok -->
<svg onload="alert('XSS')">
```
---
## 💡 Co dělá `e.preventDefault()`?
```javascript
form.addEventListener('submit', function(e) {
e.preventDefault(); // ← CO TO DĚLÁ?
// ... zbytek kódu
});
```
### Bez `e.preventDefault()`:
1. Kliknete "Odeslat"
2. Formulář se odešle na server
3. Stránka se **OBNOVÍ** (reload)
4. Ztratíte všechna data!
### S `e.preventDefault()`:
1. Kliknete "Odeslat"
2. **ZASTAVÍ** normální odeslání
3. Stránka se **NEOBNOVÍ**
4. Můžete zpracovat data v JavaScriptu!
### Příklad:
```javascript
// ❌ BEZ preventDefault - stránka se obnoví
form.addEventListener('submit', function(e) {
console.log('Odesláno!');
// → Stránka se obnoví a nic neuvidíte!
});
// ✅ S preventDefault - stránka zůstane
form.addEventListener('submit', function(e) {
e.preventDefault(); // Zastaví refresh!
console.log('Odesláno!');
// → Zpráva se zobrazí v konzoli!
});
```
---
## 🔍 Porovnání kódu:
### ❌ NEBEZPEČNÉ (innerHTML):
```javascript
const html = `<p><strong>${name}</strong>: ${message}</p>`;
entriesDiv.innerHTML += html; // SPUSTÍ JavaScript!
```
### ✅ BEZPEČNÉ (textContent):
```javascript
const div = document.createElement('div');
const strong = document.createElement('strong');
strong.textContent = name; // JEN TEXT, ne kód!
const text = document.createElement('span');
text.textContent = ': ' + message; // JEN TEXT!
div.appendChild(strong);
div.appendChild(text);
entriesDiv.appendChild(div);
```
---
## 🎓 Pro studenty:
### Zapamatujte si:
1. **innerHTML = NEBEZPEČNÉ**
- Spustí HTML a JavaScript
2. **textContent = BEZPEČNÉ**
- Zobrazí jen čistý text
3. **createElement() = BEZPEČNÉ**
- Vytvoří čisté DOM elementy
4. **Zlaté pravidlo:**
```
🚨 DON'T TRUST THE INPUT! 🚨
```
---
## 🚀 XSS útoky k vyzkoušení:
### ✅ FUNGUJÍCÍ útoky (použijte tyto!):
```html
<!-- 1. IMG útok - FUNGUJE! -->
<img src=x onerror="alert('HACKNUTÝ!')">
<!-- 2. Změna pozadí - FUNGUJE! -->
<img src=x onerror="document.body.style.background='red'">
<!-- 3. SVG útok - FUNGUJE! -->
<svg onload="alert('XSS')">
<!-- 4. Input útok - FUNGUJE! -->
<input onfocus="alert('XSS')" autofocus>
<!-- 5. Změna HTML (bez JS) - FUNGUJE! -->
<h1 style="color:red; font-size:50px">HACKED!</h1>
```
### ❌ NEFUNGUJÍCÍ útoky (prohlížeč blokuje):
```html
<!-- Script tag v innerHTML - NEFUNGUJE! -->
<script>alert('XSS')</script>
<!-- Prohlížeč tohle automaticky zablokuje -->
```
---
## 🔍 DŮLEŽITÉ: Proč `<script>` nefunguje?
### Bezpečnostní opatření prohlížečů:
**`<script>` tagy přidané přes `innerHTML` se NESPUSTÍ!**
```javascript
// ❌ Toto NESPUSTÍ JavaScript:
element.innerHTML = '<script>alert(1)</script>';
```
**Proč?** Moderní prohlížeče (Chrome, Firefox, Edge) mají bezpečnostní ochranu.
### ALE! Event handlery FUNGUJÍ:
```javascript
// ✅ Toto SPUSTÍ JavaScript:
element.innerHTML = '<img src=x onerror="alert(1)">';
```
**Proto je innerHTML STÁLE nebezpečné!**
Útočníci nepoužívají `<script>`, ale:
- `onerror` (img, video, audio)
- `onload` (svg, iframe, body)
- `onfocus` (input, textarea)
- `onmouseover` (div, span, a)
- atd.
---
---
## ⚠️ DŮLEŽITÉ!
- Toto je **jen pro vzdělávání**
- **NIKDY** nepoužívejte zranitelný kód v produkci
- Hacking bez povolení = **TRESTNÝ ČIN**
---
**Hotovo! Teď máte jednoduchou demonstraci XSS útoku.** 🎯

377
AI_extra_material/18a_form_xss_demo/ZADANI.md

@ -0,0 +1,377 @@
# Lekce 18a: XSS Demo - "Don't Trust The Input"
## 🎯 Cíl lekce
**Naučit studenty základy bezpečnosti webových aplikací** prostřednictvím praktické demonstrace XSS (Cross-Site Scripting) útoku. Studenti pochopí:
- Proč je důležité ošetřovat vstup od uživatelů
- Rozdíl mezi `innerHTML` (nebezpečné) a `textContent` (bezpečné)
- Pravidlo **"DON'T TRUST THE INPUT"**
## ⚠️ DŮLEŽITÉ UPOZORNĚNÍ
Tato lekce obsahuje **ZÁMĚRNĚ ZRANITELNÝ KÓD** pro vzdělávací účely!
- ❌ **NIKDY** nepoužívejte zranitelnou verzi v produkčním prostředí
- ✅ Vysvětlete studentům, že jde o **demonstraci bezpečnostní chyby**
- ✅ Zdůrazněte, že **hacking bez povolení je TRESTNÝ ČIN**
## 📁 Soubory v této lekci
### 1. `index.html` - Úvodní stránka
- Přehled lekce
- Vysvětlení XSS
- Porovnání nebezpečného vs. bezpečného kódu
- Doporučený postup lekce
### 2. `zranitelna_verze.html` - NEBEZPEČNÁ verze
- Návštěvní kniha s formulářem
- **Používá `innerHTML`** - umožňuje XSS útoky!
- V pravém sloupci jsou připravené XSS útoky ke zkopírování
- Červené varování nahoře
### 3. `bezpecna_verze.html` - BEZPEČNÁ verze
- Stejná návštěvní kniha
- **Používá `textContent` a `createElement()`**
- XSS útoky zde nefungují
- Zelené potvrzení bezpečnosti
- Detailní vysvětlení bezpečného kódu
## 🎓 Postup výuky (60 minut)
### Fáze 1: Úvod (10 min)
1. **Otevřete `index.html`** na projektoru
2. **Zeptejte se studentů:**
- "Myslíte si, že formuláře na webu jsou bezpečné?"
- "Co když útočník zadá do formuláře škodlivý kód?"
- "Slyšeli jste o XSS útoku?"
3. **Vysvětlete XSS:**
- Cross-Site Scripting
- Útočník vkládá škodlivý kód do webové stránky
- Kód se spustí v prohlížeči jiného uživatele
- Může ukrást hesla, cookies, osobní data
4. **Ukažte zlaté pravidlo:**
```
🚨 "DON'T TRUST THE INPUT" 🚨
Nikdy nedůvěřujte tomu, co uživatel zadá!
```
### Fáze 2: Demonstrace útoku (20 min)
1. **Otevřete `zranitelna_verze.html`**
2. **Základní funkce (2 min):**
- Ukažte normální použití formuláře
- Zadejte běžné jméno a zprávu
- Uveďte: "Takto to vypadá normálně"
3. **ÚTOK #1 - Alert (3 min):**
```html
<script>alert('Byl jsi hacknutý!')</script>
```
- Zkopírujte do pole "Zpráva"
- Odešlete formulář
- **BOOM! Alert se zobrazí!** 💥
- Vysvětlete: "To je XSS útok! JavaScript se spustil!"
4. **ÚTOK #2 - Změna stránky (3 min):**
```html
<h1 style="color:red; font-size:60px;">HACKED!</h1>
```
- Vložte do formuláře
- Odešlete
- Stránka se vizuálně změní
- Vysvětlete: "Útočník změnil HTML strukturu!"
5. **ÚTOK #3 - Krádež cookies (5 min):**
```html
<script>alert('Tvoje cookies: ' + document.cookie)</script>
```
- Vložte do formuláře
- Alert zobrazí cookies
- **KRITICKY DŮLEŽITÉ:** Vysvětlete, že v cookies mohou být:
- Session ID (přihlášení)
- Tokeny
- Osobní data
- Útočník může cookies odeslat na svůj server!
6. **ÚTOK #4 - Obrázek s onerror (3 min):**
```html
<img src=x onerror="alert('XSS útok přes obrázek!')">
```
- Tento útok funguje i když admin zakáže `<script>`
- Ukažte, že útočníci jsou kreativní
7. **Diskuze (4 min):**
- "Co si myslíte, co by se stalo na skutečném webu?"
- "Co by mohl útočník udělat s vašimi přihlašovacími údaji?"
- "Je to nebezpečné?"
### Fáze 3: Bezpečné řešení (15 min)
1. **Otevřete `bezpecna_verze.html`**
2. **Zkuste stejné útoky (5 min):**
- Vložte `<script>alert('XSS')</script>`
- Nefunguje! Zobrazí se jako text! ✅
- Zkuste další útoky - žádný nefunguje
3. **Vysvětlete rozdíl (5 min):**
- Scrollujte dolů k sekci "Jak to funguje?"
- Ukažte rozdíl v kódu:
**NEBEZPEČNÉ:**
```javascript
element.innerHTML = `<p>${message}</p>`;
// innerHTML SPUSTÍ JavaScript!
```
**BEZPEČNÉ:**
```javascript
const p = document.createElement('p');
p.textContent = message;
element.appendChild(p);
// textContent NESPUSTÍ JavaScript!
```
4. **Projděte bezpečný kód (5 min):**
- Ukažte použití `createElement()`
- Ukažte použití `textContent`
- Vysvětlete: "HTML se zobrazí jako TEXT, ne jako KÓD"
### Fáze 4: Praktické cvičení (10 min)
**Zadání pro studenty:**
1. Otevřete oba soubory vedle sebe
2. Porovnejte JavaScript kód
3. Najděte všechny rozdíly
4. Napište do poznámek:
- Co je nebezpečné?
- Co je bezpečné?
- Proč?
### Fáze 5: Shrnutí a test (5 min)
**Otázky pro studenty:**
1. ❓ "Co znamená XSS?"
- ✅ Cross-Site Scripting
2. ❓ "Proč je `innerHTML` nebezpečné?"
- ✅ Spouští HTML a JavaScript kód
3. ❓ "Co je bezpečnější: `innerHTML` nebo `textContent`?"
- ✅ `textContent`
4. ❓ "Jaké je zlaté pravidlo bezpečnosti?"
- ✅ "DON'T TRUST THE INPUT"
5. ❓ "Můžu důvěřovat tomu, co uživatel zadá do formuláře?"
- ✅ NE! NIKDY!
## 🎯 XSS útoky k vyzkoušení
### Základní útoky (pro všechny studenty):
```html
<!-- 1. Jednoduchý alert -->
<script>alert('XSS útok!')</script>
<!-- 2. Změna textu -->
<h1 style="color:red;">HACKED!</h1>
<!-- 3. Změna pozadí -->
<script>document.body.style.background = 'red'</script>
<!-- 4. Obrázek s chybou -->
<img src=x onerror="alert('XSS')">
<!-- 5. Zobrazení cookies -->
<script>alert(document.cookie)</script>
```
### Pokročilé útoky (pro šikovnější studenty):
```html
<!-- 6. Přesměrování -->
<script>window.location = 'https://google.com'</script>
<!-- 7. Změna HTML -->
<script>document.body.innerHTML = '<h1>Byl jsi hacknutý!</h1>'</script>
<!-- 8. Infinite loop (pozor, může zhavarovat!) -->
<script>while(true){alert('SPAM')}</script>
<!-- 9. Console log spam -->
<script>setInterval(()=>console.log('HACKED'), 100)</script>
<!-- 10. Krádež formulářových dat -->
<script>
const data = document.getElementById('name').value;
alert('Ukradl jsem: ' + data);
</script>
```
### Kreativní útoky (bonus):
```html
<!-- 11. Falešný login formulář -->
<div style="position:fixed; top:0; left:0; width:100%; height:100%; background:white; z-index:9999;">
<h1>Přihlášení vypršelo</h1>
<input type="text" placeholder="Uživatel">
<input type="password" placeholder="Heslo">
<button>Přihlásit</button>
</div>
<!-- 12. Vibrace (na mobilu) -->
<script>navigator.vibrate([200, 100, 200])</script>
<!-- 13. Text-to-speech (pokud podporováno) -->
<script>
const utterance = new SpeechSynthesisUtterance('Byl jsi hacknutý!');
speechSynthesis.speak(utterance);
</script>
```
## 📊 Hodnocení (doporučené)
Pokud chcete lekci ohodnotit, můžete použít tento systém:
### Praktický test (10 bodů):
1. **Identifikace problému (3b)**
- Student najde `innerHTML` v nebezpečném kódu
- Vysvětlí proč je to problém
2. **Provedení útoku (2b)**
- Student úspěšně provede XSS útok na zranitelné verzi
3. **Obrana (3b)**
- Student vysvětlí jak se bránit
- Zmíní `textContent` nebo `createElement()`
4. **Pravidlo (2b)**
- Student zná a umí vysvětlit "Don't Trust The Input"
## 💡 Tipy pro učitele
### Při výuce:
1. **Dramatizujte:**
- Když se spustí XSS útok, reagujte: "Oh ne! Stránka je kompromitovaná!"
- Studenti si to lépe zapamatují
2. **Real-world příklady:**
- Facebook měl XSS zranitelnost v 2011
- Twitter XSS worm v 2010
- eBay XSS v 2014
3. **Etika:**
- **DŮLEŽITÉ:** Zdůrazněte, že hacking bez povolení je TRESTNÝ ČIN
- Vysvětlete rozdíl mezi "ethical hacking" a kyberzločinem
- Toto je edukační prostředí
4. **Bezpečnostní myšlení:**
- Motivujte studenty myslet jako útočníci
- "Jak bych tohle mohl zneužít?"
- Pak myslet jako obránci: "Jak tomu zabráním?"
### Časté dotazy studentů:
**Q: "Kde se s XSS můžu setkat?"**
A: Všude kde je formulář: komentáře, profily, vyhledávání, chat, recenze...
**Q: "Proč vývojáři dělají takové chyby?"**
A: Někdy neznají rizika, někdy spěchají, někdy zapomenou ošetřit vstup.
**Q: "Je to jediná bezpečnostní hrozba?"**
A: Ne! Existuje SQL injection, CSRF, clickjacking, a mnoho dalších. Bezpečnost je obrovské téma.
**Q: "Stačí použít `textContent` a jsem v bezpečí?"**
A: Je to dobrý start, ale bezpečnost má mnoho vrstev. Na serveru musíte data také validovat!
**Q: "Můžu takhle hacknout Facebook?"**
A: Ne! Velké firmy mají security týmy. A bylo by to TRESTNÉ! Nikdy to nezkoušejte bez povolení.
## 🔗 Další studium
### Pro zvídavé studenty doporučte:
1. **OWASP Top 10** - seznam nejčastějších bezpečnostních hrozeb
2. **PortSwigger Web Security Academy** - zdarma kurzy o web security
3. **HackTheBox** - legální hackování (s povolením)
4. **Bug Bounty programy** - etické hackování za peníze
### Užitečné nástroje:
- **Browser DevTools (F12)** - konzole, network, elements
- **Burp Suite** - testování web aplikací
- **ZAP (Zed Attack Proxy)** - open-source security scanner
## 📝 Domácí úkol (nepovinné)
**Zadání:**
Vytvořte vlastní mini webovou aplikaci (např. TODO list nebo chat) s těmito požadavky:
1. Formulář pro přidání položky
2. Zobrazení položek na stránce
3. **Implementujte to BEZPEČNĚ** (použijte `textContent`)
4. V komentářích vysvětlete, proč je to bezpečné
5. Zkuste to "hacknout" - mělo by to selhat!
**Bonus:**
Vytvořte také zranitelnou verzi a ukažte rozdíl.
## ✅ Co by studenti měli umět po lekci
Po této lekci by studenti měli:
✅ Vědět co je XSS (Cross-Site Scripting)
✅ Umět vysvětlit proč je `innerHTML` nebezpečné
✅ Znát rozdíl mezi `innerHTML` a `textContent`
✅ Umět použít `createElement()` pro tvorbu DOM elementů
✅ Znát pravidlo "DON'T TRUST THE INPUT"
✅ Chápat proč je bezpečnost webů důležitá
✅ Vědět, že hacking bez povolení je trestný čin
✅ Mít základní bezpečnostní mindset při vývoji webů
## 🚨 Důležité poznámky
### Pro učitele:
1. **Tato lekce obsahuje funkční XSS exploity**
- Soubory jsou jen pro vzdělávací účely
- Nikdy je nenahrajte na veřejný server
- Nesdílejte je mimo bezpečné prostředí
2. **Etika a zákon:**
- Vysvětlete studentům, že:
- Hacking bez povolení = trestný čin
- V ČR: Zákon č. 40/2009 Sb. trestní zákoník, § 230
- Hrozí až 3 roky vězení
- Ethical hacking se dělá POUZE s písemným povolením
3. **Zodpovědnost:**
- Zdůrazněte odpovědnost vývojářů
- "Se schopností přichází odpovědnost"
- Vývojáři chrání data a soukromí uživatelů
## 🎉 Závěr
Tato lekce poskytuje studentům **praktickou zkušenost s bezpečnostní zranitelností** v kontrolovaném prostředí. Je to jeden z nejlepších způsobů, jak naučit důležitost bezpečného programování.
**Klíčové sdělení:**
```
🔐 BEZPEČNOST NENÍ VOLITELNÁ!
🔐 VŽDY OŠETŘUJTE VSTUP!
🔐 DON'T TRUST THE INPUT!
```
---
Vytvořeno: 2. prosince 2025
Předmět: Webové Technologie (WTL)
Cílová skupina: 3. ročník IT
Téma: Bezpečnost webových aplikací - XSS
**Hodně úspěchů při výuce! 🛡️**

157
AI_extra_material/18a_form_xss_demo/bezpecna_jednoducha.html

@ -0,0 +1,157 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Návštěvní kniha - BEZPEČNÁ ✅</title>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body class="bg-light p-4">
<div class="container">
<!-- BEZPEČNOST -->
<div class="alert alert-success">
<h3>✅ BEZPEČNÁ VERZE - nelze hacknout!</h3>
<p>Používá <code>textContent</code> - SPRÁVNĚ!</p>
</div>
<div class="row">
<!-- FORMULÁŘ -->
<div class="col-md-6">
<div class="card">
<div class="card-header bg-success text-white">
<h3>📖 Návštěvní kniha</h3>
</div>
<div class="card-body">
<form id="myForm">
<div class="mb-3">
<label class="form-label">Jméno:</label>
<input type="text" class="form-control" id="name">
</div>
<div class="mb-3">
<label class="form-label">Zpráva:</label>
<textarea class="form-control" id="message" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-success">Přidat záznam</button>
</form>
</div>
</div>
</div>
<!-- ZKUSTE HACKNOUT -->
<div class="col-md-6">
<div class="card border-success">
<div class="card-header bg-dark text-white">
<h4>🛡️ Zkuste to hacknout!</h4>
</div>
<div class="card-body">
<h5>Zkuste stejné "útoky":</h5>
<div class="alert alert-secondary">
<strong>1. Alert:</strong>
<pre><code>&lt;script&gt;alert('HACKNUTÝ!')&lt;/script&gt;</code></pre>
<small class="text-success">✅ Nefunguje!</small>
</div>
<div class="alert alert-secondary">
<strong>2. HTML:</strong>
<pre><code>&lt;h1&gt;HACKED!&lt;/h1&gt;</code></pre>
<small class="text-success">✅ Zobrazí se jako text!</small>
</div>
<div class="alert alert-info">
<strong>💡 Výsledek:</strong><br>
Vše se zobrazí jako TEXT, ne jako KÓD!
</div>
</div>
</div>
</div>
</div>
<!-- ZÁZNAMY -->
<div class="card mt-4">
<div class="card-header bg-success text-white">
<h4>📝 Záznamy</h4>
</div>
<div class="card-body">
<div id="entries">
<p class="text-muted">Zatím žádné záznamy...</p>
</div>
</div>
</div>
<!-- VYSVĚTLENÍ -->
<div class="card mt-4 border-success">
<div class="card-header bg-success text-white">
<h4>🔍 Bezpečný kód:</h4>
</div>
<div class="card-body">
<pre class="bg-light p-3"><code>// ✅ BEZPEČNÉ!
const div = document.createElement('div');
const strong = document.createElement('strong');
const text = document.createElement('span');
strong.textContent = name; // ✅ textContent = BEZPEČNÉ
text.textContent = ': ' + message; // ✅ textContent = BEZPEČNÉ
div.appendChild(strong);
div.appendChild(text);
entriesDiv.appendChild(div);</code></pre>
<div class="alert alert-success mt-3">
<strong>Proč je to bezpečné?</strong><br>
<code>textContent</code> zobrazí vše jako ČISTÝ TEXT.<br>
HTML a JavaScript se NIKDY nespustí!
</div>
<h5 class="mt-4">📊 Porovnání:</h5>
<table class="table table-bordered">
<tr class="table-danger">
<td><code>innerHTML</code></td>
<td>❌ NEBEZPEČNÉ</td>
<td>Spustí kód</td>
</tr>
<tr class="table-success">
<td><code>textContent</code></td>
<td>✅ BEZPEČNÉ</td>
<td>Jen text</td>
</tr>
</table>
</div>
</div>
</div>
<script>
// ===== BEZPEČNÝ KÓD =====
const form = document.getElementById('myForm');
const entriesDiv = document.getElementById('entries');
form.addEventListener('submit', function(e) {
e.preventDefault(); // Zastaví odeslání formuláře
// Získáme data
const name = document.getElementById('name').value;
const message = document.getElementById('message').value;
// ✅ BEZPEČNÉ: Vytvoříme elementy
const div = document.createElement('div');
div.className = 'alert alert-info';
const strong = document.createElement('strong');
strong.textContent = name; // ✅ textContent je BEZPEČNÉ!
const text = document.createElement('span');
text.textContent = ': ' + message; // ✅ textContent je BEZPEČNÉ!
// Složíme dohromady
div.appendChild(strong);
div.appendChild(text);
// Přidáme na stránku
entriesDiv.appendChild(div);
// Resetujeme formulář
form.reset();
});
</script>
</body>
</html>

335
AI_extra_material/18a_form_xss_demo/bezpecna_verze.html

@ -0,0 +1,335 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Návštěvní kniha - BEZPEČNÁ VERZE ✅</title>
<link rel="stylesheet" href="css/bootstrap.css">
<style>
.entry {
border-left: 4px solid #198754;
transition: all 0.3s;
}
.entry:hover {
background-color: #f8f9fa;
transform: translateX(5px);
}
.safe-banner {
background: linear-gradient(135deg, #198754 0%, #146c43 100%);
color: white;
padding: 20px;
margin-bottom: 30px;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(25, 135, 84, 0.3);
}
</style>
</head>
<body class="bg-light">
<!-- BEZPEČNOST BANNER -->
<div class="container mt-4">
<div class="safe-banner">
<h2>✅ BEZPEČNÁ VERZE ✅</h2>
<p class="mb-0">
<strong>Tato verze je BEZPEČNÁ!</strong> Používá <code>textContent</code> a správně ošetřuje vstup.
XSS útoky zde NEFUNGUJÍ.
</p>
</div>
</div>
<div class="container">
<div class="row">
<!-- LEVÝ SLOUPEC - Formulář -->
<div class="col-md-6">
<div class="card shadow-sm">
<div class="card-header bg-success text-white">
<h3 class="mb-0">📖 Návštěvní kniha</h3>
</div>
<div class="card-body">
<form id="guestbookForm">
<div class="mb-3">
<label for="name" class="form-label">Vaše jméno:</label>
<input type="text" class="form-control" id="name" required>
</div>
<div class="mb-3">
<label for="message" class="form-label">Zpráva:</label>
<textarea class="form-control" id="message" rows="4" required></textarea>
<div class="form-text">Napište nám, co si myslíte...</div>
</div>
<button type="submit" class="btn btn-success w-100">
💾 Přidat záznam
</button>
</form>
<div class="alert alert-success mt-3">
<small>
<strong>🔒 Tento formulář je BEZPEČNÝ!</strong><br>
Zkuste zadat HTML nebo JavaScript - nezpůsobí to nic nebezpečného.
</small>
</div>
</div>
</div>
</div>
<!-- PRAVÝ SLOUPEC - Zkuste to hacknout (nebude fungovat) -->
<div class="col-md-6">
<div class="card shadow-sm border-success">
<div class="card-header bg-dark text-white">
<h4 class="mb-0">🛡️ Zkuste to hacknout!</h4>
</div>
<div class="card-body">
<h5>Zkuste tyto "útoky" (nebudou fungovat):</h5>
<div class="alert alert-secondary">
<strong>1. Alert:</strong>
<pre class="mb-0"><code>&lt;script&gt;alert('Pokus o útok')&lt;/script&gt;</code></pre>
<small class="text-success">✅ Zobrazí se jako text, nespustí se!</small>
</div>
<div class="alert alert-secondary">
<strong>2. HTML:</strong>
<pre class="mb-0"><code>&lt;h1 style="color:red"&gt;HACKED!&lt;/h1&gt;</code></pre>
<small class="text-success">✅ Zobrazí se jako text!</small>
</div>
<div class="alert alert-secondary">
<strong>3. Obrázek:</strong>
<pre class="mb-0"><code>&lt;img src=x onerror="alert('XSS')"&gt;</code></pre>
<small class="text-success">✅ Nespustí se JavaScript!</small>
</div>
<div class="alert alert-info mt-3">
<strong>💡 Výsledek:</strong><br>
Veškerý HTML kód se zobrazí jako obyčejný text, nespustí se!
Stránka je v bezpečí. 🛡️
</div>
</div>
</div>
</div>
</div>
<!-- ZÁZNAMY -->
<div class="row mt-4">
<div class="col-12">
<div class="card shadow-sm">
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
<h4 class="mb-0">📝 Záznamy návštěvníků</h4>
<button class="btn btn-sm btn-light" onclick="clearEntries()">🗑️ Smazat vše</button>
</div>
<div class="card-body">
<div id="entries">
<div class="alert alert-info">
<em>Zatím žádné záznamy. Buďte první!</em>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- VYSVĚTLENÍ -->
<div class="row mt-4 mb-4">
<div class="col-12">
<div class="card border-success">
<div class="card-header bg-success text-white">
<h4 class="mb-0">🔍 Jak to funguje? (BEZPEČNÝ KÓD)</h4>
</div>
<div class="card-body">
<h5>Bezpečný kód v JavaScriptu:</h5>
<pre class="bg-light p-3 rounded"><code>// ✅ BEZPEČNÉ - používá createElement a textContent!
// 1. Vytvoříme elementy pomocí createElement (ne innerHTML!)
const entryDiv = document.createElement('div');
entryDiv.className = 'entry mb-3 p-3 bg-white rounded shadow-sm';
const nameStrong = document.createElement('strong');
nameStrong.style.color = '#198754';
nameStrong.style.fontSize = '1.1em';
// 2. Nastavíme text pomocí textContent (ne innerHTML!)
nameStrong.textContent = '👤 ' + name; // ✅ BEZPEČNÉ
const messagePara = document.createElement('p');
messagePara.textContent = message; // ✅ BEZPEČNÉ
// 3. Přidáme do stránky
entryDiv.appendChild(nameStrong);
entryDiv.appendChild(messagePara);
entriesDiv.insertBefore(entryDiv, entriesDiv.firstChild);</code></pre>
<div class="alert alert-success mt-3">
<strong>✅ Proč je to bezpečné?</strong>
<ul class="mb-0">
<li><code>textContent</code> vždy vkládá čistý TEXT, ne HTML</li>
<li><code>createElement()</code> vytváří čisté DOM elementy</li>
<li>Jakýkoliv <code>&lt;script&gt;</code> nebo <code>&lt;img&gt;</code> tag se zobrazí jako text</li>
<li>JavaScript kód se NIKDY nespustí</li>
<li>Stránka je chráněná před XSS útoky</li>
</ul>
</div>
<h5 class="mt-4">📚 Pravidlo #1 bezpečnosti:</h5>
<div class="alert alert-warning">
<h4 class="alert-heading">🚨 "DON'T TRUST THE INPUT"</h4>
<p><strong>NIKDY nedůvěřujte vstupu od uživatele!</strong></p>
<ul class="mb-0">
<li>Vždy ošetřujte vstup</li>
<li>Používejte <code>textContent</code> místo <code>innerHTML</code></li>
<li>Validujte data na serveru i klientu</li>
<li>Escapujte speciální znaky</li>
</ul>
</div>
<h5 class="mt-4">Porovnání:</h5>
<table class="table table-bordered">
<thead class="table-dark">
<tr>
<th>Metoda</th>
<th>Bezpečnost</th>
<th>Použití</th>
</tr>
</thead>
<tbody>
<tr class="table-danger">
<td><code>innerHTML</code></td>
<td>❌ NEBEZPEČNÉ</td>
<td>Spustí HTML a JavaScript</td>
</tr>
<tr class="table-success">
<td><code>textContent</code></td>
<td>✅ BEZPEČNÉ</td>
<td>Vloží jen čistý text</td>
</tr>
<tr class="table-success">
<td><code>createElement()</code></td>
<td>✅ BEZPEČNÉ</td>
<td>Vytvoří čistý DOM element</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<script src="js/bootstrap.bundle.js"></script>
<script>
// ===== BEZPEČNÝ KÓD - POUŽÍVEJTE TOTO! =====
const form = document.getElementById('guestbookForm');
const entriesDiv = document.getElementById('entries');
// Načteme záznamy z localStorage při načtení stránky
loadEntries();
form.addEventListener('submit', function(e) {
e.preventDefault();
// Získáme data z formuláře
const name = document.getElementById('name').value;
const message = document.getElementById('message').value;
// ✅ BEZPEČNÉ: Vytvoříme elementy pomocí DOM API
createEntry(name, message);
// Uložíme do localStorage
saveEntry(name, message);
// Resetujeme formulář
form.reset();
});
function createEntry(name, message) {
// Smažeme "žádné záznamy" zprávu pokud existuje
const emptyAlert = entriesDiv.querySelector('.alert-info');
if (emptyAlert) {
emptyAlert.remove();
}
// ✅ KROK 1: Vytvoříme hlavní kontejner
const entryDiv = document.createElement('div');
entryDiv.className = 'entry mb-3 p-3 bg-white rounded shadow-sm';
// ✅ KROK 2: Vytvoříme header s jménem a časem
const headerDiv = document.createElement('div');
headerDiv.className = 'd-flex justify-content-between align-items-start';
const nameDiv = document.createElement('div');
const nameStrong = document.createElement('strong');
nameStrong.style.color = '#198754';
nameStrong.style.fontSize = '1.1em';
nameStrong.textContent = '👤 ' + name; // ✅ textContent je BEZPEČNÉ!
const timeSmall = document.createElement('small');
timeSmall.className = 'text-muted ms-2';
timeSmall.textContent = new Date().toLocaleString('cs-CZ');
nameDiv.appendChild(nameStrong);
nameDiv.appendChild(timeSmall);
headerDiv.appendChild(nameDiv);
// ✅ KROK 3: Přidáme oddělovač
const hr = document.createElement('hr');
// ✅ KROK 4: Vytvoříme zprávu
const messagePara = document.createElement('p');
messagePara.className = 'mb-0';
messagePara.textContent = message; // ✅ textContent je BEZPEČNÉ!
// ✅ KROK 5: Složíme vše dohromady
entryDiv.appendChild(headerDiv);
entryDiv.appendChild(hr);
entryDiv.appendChild(messagePara);
// ✅ KROK 6: Přidáme na začátek seznamu
entriesDiv.insertBefore(entryDiv, entriesDiv.firstChild);
}
function saveEntry(name, message) {
// Získáme existující záznamy
let entries = JSON.parse(localStorage.getItem('guestbook_safe') || '[]');
// Přidáme nový záznam
entries.unshift({
name: name,
message: message,
timestamp: new Date().toISOString()
});
// Uložíme zpět
localStorage.setItem('guestbook_safe', JSON.stringify(entries));
}
function loadEntries() {
const entries = JSON.parse(localStorage.getItem('guestbook_safe') || '[]');
if (entries.length === 0) {
return;
}
// Smažeme prázdnou zprávu
entriesDiv.innerHTML = '';
// ✅ Vytvoříme každý záznam BEZPEČNĚ
entries.forEach(entry => {
createEntry(entry.name, entry.message);
});
}
function clearEntries() {
if (confirm('Opravdu chcete smazat všechny záznamy?')) {
localStorage.removeItem('guestbook_safe');
entriesDiv.innerHTML = '<div class="alert alert-info"><em>Zatím žádné záznamy. Buďte první!</em></div>';
}
}
// Info pro console
console.log('%c✅ BEZPEČNÁ VERZE ✅', 'color: green; font-size: 20px; font-weight: bold;');
console.log('Tato stránka je CHRÁNĚNÁ před XSS útoky!');
console.log('Používá textContent a createElement() místo innerHTML.');
</script>
</body>
</html>

12048
AI_extra_material/18a_form_xss_demo/css/bootstrap.css

File diff suppressed because it is too large

6
AI_extra_material/18a_form_xss_demo/css/bootstrap.min.css

File diff suppressed because one or more lines are too long

313
AI_extra_material/18a_form_xss_demo/index.html

@ -0,0 +1,313 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XSS Demo - Don't Trust The Input</title>
<link rel="stylesheet" href="css/bootstrap.css">
<style>
.hero {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 60px 0;
margin-bottom: 40px;
}
.version-card {
transition: transform 0.3s, box-shadow 0.3s;
height: 100%;
}
.version-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
}
</style>
</head>
<body>
<!-- HERO SEKCE -->
<div class="hero">
<div class="container text-center">
<h1 class="display-3 mb-3">🛡️ XSS Security Demo</h1>
<p class="lead">Lekce bezpečnosti: "Don't Trust The Input"</p>
<p class="fs-5">Porovnání zranitelné vs. bezpečné implementace formuláře</p>
</div>
</div>
<div class="container mb-5">
<!-- CO SE NAUČÍTE -->
<div class="row mb-5">
<div class="col-12">
<div class="card shadow">
<div class="card-body">
<h2 class="card-title">🎯 Co se v této lekci naučíte:</h2>
<div class="row mt-4">
<div class="col-md-6">
<ul class="list-unstyled">
<li class="mb-2">✅ Co je XSS (Cross-Site Scripting) útok</li>
<li class="mb-2">✅ Jak funguje nebezpečný kód s <code>innerHTML</code></li>
<li class="mb-2">✅ Jak útočníci zneužívají formuláře</li>
<li class="mb-2">✅ Reálné příklady XSS útoků</li>
</ul>
</div>
<div class="col-md-6">
<ul class="list-unstyled">
<li class="mb-2">✅ Jak správně ošetřit vstup od uživatele</li>
<li class="mb-2">✅ Použití <code>textContent</code> místo <code>innerHTML</code></li>
<li class="mb-2">✅ Bezpečné vytváření DOM elementů</li>
<li class="mb-2">✅ Pravidlo "Don't Trust The Input"</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- POROVNÁNÍ VERZÍ -->
<h2 class="text-center mb-4">🔍 Vyberte verzi k testování:</h2>
<div class="row g-4">
<!-- ZRANITELNÁ VERZE -->
<div class="col-md-6">
<div class="card version-card border-danger border-3">
<div class="card-header bg-danger text-white text-center">
<h3 class="mb-0">⚠️ ZRANITELNÁ VERZE</h3>
</div>
<div class="card-body">
<div class="text-center mb-3">
<span class="badge bg-danger fs-5">NEBEZPEČNÁ</span>
</div>
<h5>Co tato verze dělá ŠPATNĚ:</h5>
<ul>
<li>Používá <code>innerHTML</code></li>
<li>Neošetřuje vstup od uživatele</li>
<li>Spouští HTML a JavaScript kód</li>
<li>Je zranitelná vůči XSS útokům</li>
</ul>
<div class="alert alert-danger">
<strong>⚠️ Varování:</strong> Toto je ukázka jak <strong>NEDĚLAT</strong> webové aplikace!
</div>
<h5 class="mt-3">Zkuste tyto útoky:</h5>
<div class="bg-light p-2 rounded mb-2">
<code>&lt;script&gt;alert('XSS')&lt;/script&gt;</code>
</div>
<div class="bg-light p-2 rounded mb-2">
<code>&lt;h1&gt;HACKED!&lt;/h1&gt;</code>
</div>
<div class="bg-light p-2 rounded">
<code>&lt;img src=x onerror="alert('Útok')"&gt;</code>
</div>
<div class="d-grid gap-2 mt-4">
<a href="zranitelna_verze.html" class="btn btn-danger btn-lg">
🔓 Otevřít zranitelnou verzi
</a>
</div>
</div>
</div>
</div>
<!-- BEZPEČNÁ VERZE -->
<div class="col-md-6">
<div class="card version-card border-success border-3">
<div class="card-header bg-success text-white text-center">
<h3 class="mb-0">✅ BEZPEČNÁ VERZE</h3>
</div>
<div class="card-body">
<div class="text-center mb-3">
<span class="badge bg-success fs-5">BEZPEČNÁ</span>
</div>
<h5>Co tato verze dělá SPRÁVNĚ:</h5>
<ul>
<li>Používá <code>textContent</code></li>
<li>Používá <code>createElement()</code></li>
<li>Ošetřuje veškerý vstup</li>
<li>XSS útoky nefungují!</li>
</ul>
<div class="alert alert-success">
<strong>✅ Bezpečnost:</strong> Toto je správný způsob, jak psát bezpečné webové aplikace!
</div>
<h5 class="mt-3">Zkuste "hacknout":</h5>
<div class="bg-light p-2 rounded mb-2">
<code>&lt;script&gt;alert('XSS')&lt;/script&gt;</code>
<span class="text-success">→ Zobrazí jako text ✅</span>
</div>
<div class="bg-light p-2 rounded mb-2">
<code>&lt;h1&gt;HACKED!&lt;/h1&gt;</code>
<span class="text-success">→ Zobrazí jako text ✅</span>
</div>
<div class="bg-light p-2 rounded">
<code>&lt;img src=x onerror="alert('Útok')"&gt;</code>
<span class="text-success">→ Nespustí se ✅</span>
</div>
<div class="d-grid gap-2 mt-4">
<a href="bezpecna_verze.html" class="btn btn-success btn-lg">
🔒 Otevřít bezpečnou verzi
</a>
</div>
</div>
</div>
</div>
</div>
<!-- CO JE XSS -->
<div class="row mt-5">
<div class="col-12">
<div class="card shadow">
<div class="card-header bg-dark text-white">
<h3 class="mb-0">🧠 Co je XSS (Cross-Site Scripting)?</h3>
</div>
<div class="card-body">
<p class="lead">
XSS je bezpečnostní zranitelnost, která umožňuje útočníkovi vložit škodlivý kód
(obvykle JavaScript) do webové stránky.
</p>
<div class="row mt-4">
<div class="col-md-6">
<h5>🔴 Co může útočník udělat:</h5>
<ul>
<li>Ukrást přihlašovací údaje (cookies, session)</li>
<li>Změnit obsah stránky</li>
<li>Přesměrovat na phishingovou stránku</li>
<li>Instalovat keylogger (zaznamenávat stisky kláves)</li>
<li>Spustit malware</li>
<li>Zneužít identitu uživatele</li>
</ul>
</div>
<div class="col-md-6">
<h5>🛡️ Jak se bránit:</h5>
<ul>
<li><strong>Nikdy nedůvěřujte vstupu!</strong> (Don't Trust The Input)</li>
<li>Používejte <code>textContent</code> místo <code>innerHTML</code></li>
<li>Používejte <code>createElement()</code> pro DOM elementy</li>
<li>Validujte a sanitizujte vstup</li>
<li>Escapujte HTML entity</li>
<li>Používejte Content Security Policy (CSP)</li>
</ul>
</div>
</div>
<div class="alert alert-warning mt-4">
<h5 class="alert-heading">⚡ Zlaté pravidlo bezpečnosti:</h5>
<p class="mb-0 fs-5">
<strong>"DON'T TRUST THE INPUT"</strong> - Nikdy nedůvěřujte tomu, co uživatel zadá do formuláře!
</p>
</div>
</div>
</div>
</div>
</div>
<!-- POSTUP LEKCE -->
<div class="row mt-5">
<div class="col-12">
<div class="card shadow border-primary">
<div class="card-header bg-primary text-white">
<h3 class="mb-0">📚 Doporučený postup lekce:</h3>
</div>
<div class="card-body">
<ol class="fs-5">
<li class="mb-3">
<strong>Krok 1:</strong> Nejdřív otevřete <span class="badge bg-danger">ZRANITELNOU VERZI</span>
<ul class="mt-2">
<li>Vyzkoušejte si XSS útoky z pravého sloupce</li>
<li>Zkopírujte kód a vložte do formuláře</li>
<li>Pozorujte, co se stane!</li>
</ul>
</li>
<li class="mb-3">
<strong>Krok 2:</strong> Prostudujte si kód ve spodní sekci "Co se děje pod kapotou"
<ul class="mt-2">
<li>Pochopte proč je <code>innerHTML</code> nebezpečné</li>
<li>Podívejte se do konzole (F12)</li>
</ul>
</li>
<li class="mb-3">
<strong>Krok 3:</strong> Otevřete <span class="badge bg-success">BEZPEČNOU VERZI</span>
<ul class="mt-2">
<li>Zkuste stejné útoky - nebudou fungovat!</li>
<li>Pochopte rozdíl v přístupu</li>
</ul>
</li>
<li class="mb-3">
<strong>Krok 4:</strong> Prostudujte si bezpečný kód
<ul class="mt-2">
<li>Naučte se používat <code>textContent</code></li>
<li>Naučte se <code>createElement()</code></li>
</ul>
</li>
<li>
<strong>Krok 5:</strong> Zapamatujte si pravidlo <strong>"DON'T TRUST THE INPUT"</strong>
</li>
</ol>
</div>
</div>
</div>
</div>
<!-- POROVNÁNÍ KÓDU -->
<div class="row mt-5 mb-5">
<div class="col-12">
<div class="card shadow">
<div class="card-header bg-info text-white">
<h3 class="mb-0">💻 Porovnání kódu</h3>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h5 class="text-danger">❌ NEBEZPEČNÝ KÓD:</h5>
<pre class="bg-danger bg-opacity-10 p-3 rounded"><code>// ❌ ŠPATNĚ - innerHTML!
const html = `
&lt;div&gt;
&lt;strong&gt;${name}&lt;/strong&gt;
&lt;p&gt;${message}&lt;/p&gt;
&lt;/div&gt;
`;
element.innerHTML = html;
// Pokud message obsahuje:
// &lt;script&gt;alert('XSS')&lt;/script&gt;
// → SPUSTÍ SE!</code></pre>
</div>
<div class="col-md-6">
<h5 class="text-success">✅ BEZPEČNÝ KÓD:</h5>
<pre class="bg-success bg-opacity-10 p-3 rounded"><code>// ✅ SPRÁVNĚ - createElement!
const div = document.createElement('div');
const strong = document.createElement('strong');
strong.textContent = name;
const p = document.createElement('p');
p.textContent = message;
div.appendChild(strong);
div.appendChild(p);
element.appendChild(div);
// HTML kód se zobrazí jako TEXT
// → BEZPEČNÉ!</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<footer class="bg-dark text-white py-4">
<div class="container text-center">
<p class="mb-0">🛡️ XSS Security Demo | WTL 2025 | Lekce 18a</p>
<p class="mb-0"><small>Remember: <strong>DON'T TRUST THE INPUT!</strong></small></p>
</div>
</footer>
<script src="js/bootstrap.bundle.js"></script>
</body>
</html>

6312
AI_extra_material/18a_form_xss_demo/js/bootstrap.bundle.js

File diff suppressed because it is too large

7
AI_extra_material/18a_form_xss_demo/js/bootstrap.bundle.min.js

File diff suppressed because one or more lines are too long

154
AI_extra_material/18a_form_xss_demo/zranitelna_jednoducha.html

@ -0,0 +1,154 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Návštěvní kniha - ZRANITELNÁ ⚠️</title>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body class="bg-light p-4">
<div class="container">
<!-- VAROVÁNÍ -->
<div class="alert alert-danger">
<h3>⚠️ NEBEZPEČNÁ VERZE - lze hacknout!</h3>
<p>Používá <code>innerHTML</code> - ŠPATNĚ!</p>
</div>
<div class="row">
<!-- FORMULÁŘ -->
<div class="col-md-6">
<div class="card">
<div class="card-header bg-danger text-white">
<h3>📖 Návštěvní kniha</h3>
</div>
<div class="card-body">
<form id="myForm">
<div class="mb-3">
<label class="form-label">Jméno:</label>
<input type="text" class="form-control" id="name">
</div>
<div class="mb-3">
<label class="form-label">Zpráva:</label>
<textarea class="form-control" id="message" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-danger">Přidat záznam</button>
</form>
</div>
</div>
</div>
<!-- ÚTOKY -->
<div class="col-md-6">
<div class="card border-danger">
<div class="card-header bg-dark text-white">
<h4>🎯 Zkuste tyto útoky:</h4>
</div>
<div class="card-body">
<h5>Do pole "Zpráva" zkopírujte:</h5>
<div class="alert alert-success mb-2">
<strong>✅ 1. IMG útok (FUNGUJE!):</strong>
<pre class="mb-0"><code>&lt;img src=x onerror="alert('HACKNUTÝ!')"&gt;</code></pre>
</div>
<div class="alert alert-success mb-2">
<strong>✅ 2. Změna pozadí (FUNGUJE!):</strong>
<pre class="mb-0"><code>&lt;img src=x onerror="document.body.style.background='red'"&gt;</code></pre>
</div>
<div class="alert alert-success mb-2">
<strong>✅ 3. Změna HTML (FUNGUJE!):</strong>
<pre class="mb-0"><code>&lt;h1 style="color:red; font-size:50px"&gt;HACKED!&lt;/h1&gt;</code></pre>
</div>
<div class="alert alert-secondary mb-2">
<strong>❌ 4. Script tag (NEFUNGUJE):</strong>
<pre class="mb-0"><code>&lt;script&gt;alert('XSS')&lt;/script&gt;</code></pre>
<small class="text-muted">Prohlížeč blokuje script v innerHTML</small>
</div>
<div class="alert alert-info">
<strong>💡 Poznámka:</strong><br>
<code>&lt;script&gt;</code> v innerHTML nefunguje, ale <strong>event handlery ANO</strong>!<br>
Proto je innerHTML STÁLE nebezpečné!
</div>
</div>
</div>
</div>
</div>
<!-- ZÁZNAMY -->
<div class="card mt-4">
<div class="card-header bg-primary text-white">
<h4>📝 Záznamy</h4>
</div>
<div class="card-body">
<div id="entries">
<p class="text-muted">Zatím žádné záznamy...</p>
</div>
</div>
</div>
<!-- VYSVĚTLENÍ -->
<div class="card mt-4 border-warning">
<div class="card-header bg-warning">
<h4>🔍 Problematický kód:</h4>
</div>
<div class="card-body">
<pre class="bg-light p-3"><code>// ❌ NEBEZPEČNÉ!
const html = `&lt;p&gt;&lt;strong&gt;${name}&lt;/strong&gt;: ${message}&lt;/p&gt;`;
entriesDiv.innerHTML += html; // TADY JE PROBLÉM!</code></pre>
<div class="alert alert-danger mt-3 mb-0">
<h5 class="alert-heading">⚠️ Proč je to nebezpečné?</h5>
<p><strong>innerHTML spustí HTML a event handlery!</strong></p>
<h6 class="mt-3">❌ Nefunguje (prohlížeč blokuje):</h6>
<ul>
<li><code>&lt;script&gt;alert(1)&lt;/script&gt;</code> - NESPUSTÍ SE</li>
</ul>
<h6 class="mt-3">✅ Funguje (útočníci tohle používají!):</h6>
<ul class="mb-0">
<li><code>&lt;img src=x onerror="alert(1)"&gt;</code> - SPUSTÍ SE!</li>
<li><code>&lt;body onload="alert(1)"&gt;</code> - SPUSTÍ SE!</li>
<li><code>&lt;svg onload="alert(1)"&gt;</code> - SPUSTÍ SE!</li>
<li><code>&lt;input onfocus="alert(1)" autofocus&gt;</code> - SPUSTÍ SE!</li>
</ul>
</div>
</div>
</div>
</div>
<script>
// ===== ZRANITELNÝ KÓD =====
const form = document.getElementById('myForm');
const entriesDiv = document.getElementById('entries');
// Co dělá e.preventDefault()?
// → Zastaví normální chování formuláře (odeslání a reload stránky)
// → Abychom mohli zpracovat data sami přes JavaScript
form.addEventListener('submit', function(e) {
e.preventDefault(); // Zastaví odeslání formuláře!
// Získáme data
const name = document.getElementById('name').value;
const message = document.getElementById('message').value;
// ❌ PROBLÉM: Vytvoříme HTML string
const html = `
<div class="alert alert-info">
<strong>${name}</strong>: ${message}
</div>
`;
// ❌ KRITICKÝ PROBLÉM: innerHTML spustí JavaScript!
entriesDiv.innerHTML += html;
// Resetujeme formulář
form.reset();
});
</script>
</body>
</html>

273
AI_extra_material/18a_form_xss_demo/zranitelna_verze.html

@ -0,0 +1,273 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Návštěvní kniha - ZRANITELNÁ VERZE ⚠️</title>
<link rel="stylesheet" href="css/bootstrap.css">
<style>
.entry {
border-left: 4px solid #0d6efd;
transition: all 0.3s;
}
.entry:hover {
background-color: #f8f9fa;
transform: translateX(5px);
}
.danger-banner {
background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
color: white;
padding: 20px;
margin-bottom: 30px;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(220, 53, 69, 0.3);
}
</style>
</head>
<body class="bg-light">
<!-- NEBEZPEČÍ BANNER -->
<div class="container mt-4">
<div class="danger-banner">
<h2>⚠️ VAROVÁNÍ: ZRANITELNÁ VERZE ⚠️</h2>
<p class="mb-0">
<strong>Tato verze JE ZÁMĚRNĚ NEBEZPEČNÁ!</strong> Používá <code>innerHTML</code> bez ošetření vstupu.
Lze ji zneužít pomocí XSS (Cross-Site Scripting) útoku.
</p>
</div>
</div>
<div class="container">
<div class="row">
<!-- LEVÝ SLOUPEC - Formulář -->
<div class="col-md-6">
<div class="card shadow-sm">
<div class="card-header bg-danger text-white">
<h3 class="mb-0">📖 Návštěvní kniha</h3>
</div>
<div class="card-body">
<form id="guestbookForm">
<div class="mb-3">
<label for="name" class="form-label">Vaše jméno:</label>
<input type="text" class="form-control" id="name" required>
</div>
<div class="mb-3">
<label for="message" class="form-label">Zpráva:</label>
<textarea class="form-control" id="message" rows="4" required></textarea>
<div class="form-text">Napište nám, co si myslíte...</div>
</div>
<button type="submit" class="btn btn-danger w-100">
💾 Přidat záznam
</button>
</form>
<div class="alert alert-warning mt-3">
<small>
<strong>🔓 Tento formulář NEOŠETŘUJE vstup!</strong><br>
Zkuste zadat HTML nebo JavaScript kód...
</small>
</div>
</div>
</div>
</div>
<!-- PRAVÝ SLOUPEC - Nápověda pro hackování -->
<div class="col-md-6">
<div class="card shadow-sm border-danger">
<div class="card-header bg-dark text-white">
<h4 class="mb-0">🎯 Návody na útoky</h4>
</div>
<div class="card-body">
<h5>Zkuste tyto XSS útoky:</h5>
<div class="alert alert-danger">
<strong>1. Jednoduchý alert:</strong>
<pre class="mb-0"><code>&lt;script&gt;alert('Byl jsi hacknutý!')&lt;/script&gt;</code></pre>
</div>
<div class="alert alert-danger">
<strong>2. Změna stránky:</strong>
<pre class="mb-0"><code>&lt;h1 style="color:red"&gt;HACKED!&lt;/h1&gt;</code></pre>
</div>
<div class="alert alert-danger">
<strong>3. Obrázek s chybou:</strong>
<pre class="mb-0"><code>&lt;img src=x onerror="alert('XSS')"&gt;</code></pre>
</div>
<div class="alert alert-danger">
<strong>4. Krádež cookies:</strong>
<pre class="mb-0"><code>&lt;script&gt;alert(document.cookie)&lt;/script&gt;</code></pre>
</div>
<div class="alert alert-danger">
<strong>5. Nekonečná smyčka:</strong>
<pre class="mb-0"><code>&lt;script&gt;while(true){alert('SPAM')}&lt;/script&gt;</code></pre>
</div>
<div class="alert alert-info mt-3">
<strong>💡 Tip:</strong> Zkopírujte kód výše a vložte do formuláře!
</div>
</div>
</div>
</div>
</div>
<!-- ZÁZNAMY -->
<div class="row mt-4">
<div class="col-12">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
<h4 class="mb-0">📝 Záznamy návštěvníků</h4>
<button class="btn btn-sm btn-light" onclick="clearEntries()">🗑️ Smazat vše</button>
</div>
<div class="card-body">
<div id="entries">
<div class="alert alert-info">
<em>Zatím žádné záznamy. Buďte první!</em>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- VYSVĚTLENÍ -->
<div class="row mt-4 mb-4">
<div class="col-12">
<div class="card border-warning">
<div class="card-header bg-warning">
<h4 class="mb-0">🔍 Co se děje "pod kapotou"?</h4>
</div>
<div class="card-body">
<h5>Problematický kód v JavaScriptu:</h5>
<pre class="bg-light p-3 rounded"><code>// ❌ NEBEZPEČNÉ - používá innerHTML!
const entryHTML = `
&lt;div class="entry mb-3 p-3 bg-white rounded"&gt;
&lt;strong&gt;${name}&lt;/strong&gt;
&lt;p&gt;${message}&lt;/p&gt;
&lt;/div&gt;
`;
entriesDiv.innerHTML += entryHTML; // PROBLÉM JE TADY!</code></pre>
<div class="alert alert-danger mt-3">
<strong>⚠️ Proč je to nebezpečné?</strong><br>
Když použijeme <code>innerHTML</code>, prohlížeč SPUSTÍ veškerý HTML a JavaScript kód, který uživatel zadá!
Útočník může:
<ul class="mb-0">
<li>Spustit libovolný JavaScript</li>
<li>Ukrást cookies (přihlašovací údaje)</li>
<li>Změnit vzhled stránky</li>
<li>Přesměrovat na phishingovou stránku</li>
<li>Instalovat keylogger</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="js/bootstrap.bundle.js"></script>
<script>
// ===== ZRANITELNÝ KÓD - NEPOUŽÍVEJTE V PRODUKCI! =====
const form = document.getElementById('guestbookForm');
const entriesDiv = document.getElementById('entries');
// Načteme záznamy z localStorage při načtení stránky
loadEntries();
form.addEventListener('submit', function(e) {
e.preventDefault();
// Získáme data z formuláře
const name = document.getElementById('name').value;
const message = document.getElementById('message').value;
// ❌ PROBLÉM: Vytvoříme HTML pomocí template literálu
// Toto NEOŠETŘUJE uživatelský vstup!
const entryHTML = `
<div class="entry mb-3 p-3 bg-white rounded shadow-sm">
<div class="d-flex justify-content-between align-items-start">
<div>
<strong style="color: #0d6efd; font-size: 1.1em;">👤 ${name}</strong>
<small class="text-muted ms-2">${new Date().toLocaleString('cs-CZ')}</small>
</div>
</div>
<hr>
<p class="mb-0">${message}</p>
</div>
`;
// ❌ KRITICKÝ PROBLÉM: innerHTML spustí veškerý JavaScript!
if (entriesDiv.querySelector('.alert-info')) {
entriesDiv.innerHTML = '';
}
entriesDiv.innerHTML = entryHTML + entriesDiv.innerHTML;
// Uložíme do localStorage
saveEntry(name, message);
// Resetujeme formulář
form.reset();
});
function saveEntry(name, message) {
// Získáme existující záznamy
let entries = JSON.parse(localStorage.getItem('guestbook_vulnerable') || '[]');
// Přidáme nový záznam
entries.unshift({
name: name,
message: message,
timestamp: new Date().toISOString()
});
// Uložíme zpět
localStorage.setItem('guestbook_vulnerable', JSON.stringify(entries));
}
function loadEntries() {
const entries = JSON.parse(localStorage.getItem('guestbook_vulnerable') || '[]');
if (entries.length === 0) {
return;
}
entriesDiv.innerHTML = '';
entries.forEach(entry => {
// ❌ Opět používáme innerHTML - NEBEZPEČNÉ!
const entryHTML = `
<div class="entry mb-3 p-3 bg-white rounded shadow-sm">
<div class="d-flex justify-content-between align-items-start">
<div>
<strong style="color: #0d6efd; font-size: 1.1em;">👤 ${entry.name}</strong>
<small class="text-muted ms-2">${new Date(entry.timestamp).toLocaleString('cs-CZ')}</small>
</div>
</div>
<hr>
<p class="mb-0">${entry.message}</p>
</div>
`;
entriesDiv.innerHTML += entryHTML;
});
}
function clearEntries() {
if (confirm('Opravdu chcete smazat všechny záznamy?')) {
localStorage.removeItem('guestbook_vulnerable');
entriesDiv.innerHTML = '<div class="alert alert-info"><em>Zatím žádné záznamy. Buďte první!</em></div>';
}
}
// BONUS: Ukázka co útočník může udělat
// (Toto je jen pro demonstraci - v reálném útoku by to bylo skryté)
console.log('%c⚠️ BEZPEČNOSTNÍ VAROVÁNÍ ⚠️', 'color: red; font-size: 20px; font-weight: bold;');
console.log('Tato stránka je ZRANITELNÁ vůči XSS útokům!');
console.log('Zkuste zadat do formuláře: <script>alert("XSS útok!")</script>');
</script>
</body>
</html>

249
AI_extra_material/AI_PROJEKTY_README.md

@ -0,0 +1,249 @@
# 🤖 AI Projekty - Příprava na Bootstrap
Tyto projekty byly vytvořeny pro důkladné procvičení HTML, CSS a JavaScript konceptů před začátkem práce s Bootstrap frameworkem.
## 📋 Přehled projektů
### 🎨 AI 01 - CSS Grid & Responzivní Layout
**Složitost:** ⭐⭐ Střední
**Čas:** 45-60 minut
**Zaměření:** CSS Grid, pokročilé selektory, media queries
**Co se naučíte:**
- CSS Grid (grid-template-columns, gap)
- nth-child, first-child, last-child selektory
- Responzivní design s media queries
- CSS transformace při hover
**Soubory:**
- `ai_01_grid_responsive/ZADANI.md` - Detailní zadání
- `ai_01_grid_responsive/index.html` - Startovací HTML
- `ai_01_grid_responsive/style.css` - CSS šablona
- `ai_01_grid_responsive/reseni.html` - Kompletní řešení
- `ai_01_grid_responsive/reseni.css` - CSS řešení s komentáři
---
### 🏗️ AI 02 - Sémantické HTML5 & CSS Positioning
**Složitost:** ⭐⭐⭐ Náročné
**Čas:** 60-90 minut
**Zaměření:** Sémantické elementy, positioning, jednotky
**Co se naučíte:**
- HTML5 sémantické elementy (nav, main, section, article, aside)
- Position: fixed, sticky, relative, absolute
- CSS jednotky: rem, em, vh, vw
- Strukturu moderní webové stránky
**Soubory:**
- `ai_02_semantic_portfolio/ZADANI.md`
- `ai_02_semantic_portfolio/index.html`
- `ai_02_semantic_portfolio/style.css`
- `ai_02_semantic_portfolio/reseni.html`
- `ai_02_semantic_portfolio/reseni.css`
---
### ✅ AI 03 - Pokročilá Validace Formulářů
**Složitost:** ⭐⭐⭐ Náročné
**Čas:** 90-120 minut
**Zaměření:** JavaScript validace, event handling, RegEx
**Co se naučíte:**
- addEventListener vs inline events
- Form validation s JavaScriptem
- Regulární výrazy (RegEx)
- DOM manipulace (classList, innerHTML)
- Real-time validace s visual feedbackem
**Soubory:**
- `ai_03_form_validation/ZADANI.md`
- `ai_03_form_validation/index.html`
- `ai_03_form_validation/style.css`
- `ai_03_form_validation/script.js`
- `ai_03_form_validation/reseni.html`
- `ai_03_form_validation/reseni.css`
- `ai_03_form_validation/reseni.js`
---
### 🚀 AI 04 - Komplexní Bootstrap Prep Projekt
**Složitost:** ⭐⭐⭐⭐ Velmi náročné
**Čas:** 4-6 hodin
**Zaměření:** Komplexní projekt kombinující VŠE
**Co se naučíte:**
- Všechny předchozí koncepty dohromady
- CSS proměnné (custom properties)
- Pokročilé animace
- Scroll efekty
- Modal okna, accordions
- Mobile-first přístup
**Soubory:**
- `ai_04_prep_bootstrap/ZADANI.md` - Komplexní zadání
- `ai_04_prep_bootstrap/index.html`
- `ai_04_prep_bootstrap/css/style.css`
- `ai_04_prep_bootstrap/css/animations.css`
- `ai_04_prep_bootstrap/js/main.js`
- `ai_04_prep_bootstrap/js/validation.js`
- `ai_04_prep_bootstrap/js/scroll.js`
- `ai_04_prep_bootstrap/RESENI_PRIKLAD.md` - Tips & příklady
---
## 🎯 Doporučený postup
### Týden 1:
- **Den 1-2:** AI 01 - CSS Grid (+ opakování Grid konceptů)
- **Den 3-4:** AI 02 - Sémantika & Positioning (+ opakování HTML5)
### Týden 2:
- **Den 1-3:** AI 03 - Validace formulářů (+ opakování JavaScript)
- **Den 4-5:** Příprava na AI 04 (zopakovat vše)
### Týden 3:
- **Celý týden:** AI 04 - Komplexní projekt
- **Prezentace:** Konec týdne
### Týden 4:
- **Začátek Bootstrap!** 🎉
---
## 📚 Co budete znát po dokončení všech projektů
### HTML:
✅ Sémantické HTML5 elementy
✅ Formuláře a jejich atributy
✅ Správná struktura dokumentu
✅ Accessibility best practices
### CSS:
✅ CSS Grid systém
✅ Flexbox
✅ Positioning (všechny typy)
✅ Media queries & responzivita
✅ CSS proměnné
✅ Jednotky (rem, em, vh, vw)
✅ Pseudo-třídy a pseudo-elementy
✅ Animations & transitions
✅ Gradienty, shadows, filters
### JavaScript:
✅ DOM manipulace
✅ Event handling (addEventListener)
✅ Form validation
✅ Podmínky a cykly
✅ Funkce (function declaration, arrow functions)
✅ Regulární výrazy (RegEx)
✅ Práce s objekty a poli
---
## 🔍 Proč tyto projekty před Bootstrapem?
Bootstrap je mocný framework, ale bez pochopení základních konceptů můžete:
- Neumět framework přizpůsobit svým potřebám
- Vytvářet neefektivní kód
- Záviset na frameworku místo pochopení problému
- Mít problém při debugování
**Po těchto projektech budete:**
- Rozumět, co Bootstrap dělá "pod kapotou"
- Umět rozhodnout, kdy Bootstrap použít a kdy ne
- Efektivně přizpůsobovat Bootstrap komponenty
- Psát lepší a čistší kód
---
## 💡 Tips pro studenty
### Při řešení projektů:
1. **Nejdřív HTML struktura** - Vždy začněte správnou HTML strukturou
2. **Pak mobile styling** - CSS začněte od mobile verzí (mobile-first)
3. **JavaScript na konec** - Interaktivitu přidávejte, když máte hotové HTML & CSS
4. **Časté testování** - Testujte často v browseru, nečekejte na konec
5. **Developer tools** - Používejte Chrome DevTools (F12) pro debugování
6. **Commit často** - Pokud používáte Git, commitujte po každé sekci
### Užitečné VS Code extensions:
- Live Server - pro live reload
- Prettier - pro formátování kódu
- Auto Rename Tag - automatické přejmenování párových tagů
- CSS Peek - rychlý náhled CSS definic
### Keyboard shortcuts:
- `Ctrl + /` - zakomentovat/odkomentovat
- `Alt + Shift + F` - formátovat dokument
- `Ctrl + D` - vybrat další výskyt slova
- `Alt + Up/Down` - přesunout řádek nahoru/dolů
---
## 🆘 Když si nevíte rady
1. **Přečtěte si zadání znovu** - Často je odpověď v zadání
2. **Podívejte se na předchozí lekce** - V `01_uvod``11_json` najdete příklady
3. **Použijte console.log()** - Pro debugging JavaScriptu
4. **Zkontrolujte Developer Tools** - Konzole často ukazuje chyby
5. **Postupujte po malých krocích** - Neřešte vše najednou
6. **Koukněte na reseni.html/css/js** - Ale zkuste to sami nejdřív!
---
## 📊 Self-assessment checklist
Po dokončení všech projektů byste měli umět odpovědět ANO na tyto otázky:
### HTML:
- [ ] Znám rozdíl mezi `<div>` a sémantickými elementy?
- [ ] Umím vytvořit správnou strukturu formuláře?
- [ ] Vím, kdy použít `<section>`, `<article>`, `<aside>`?
### CSS:
- [ ] Rozumím rozdílu mezi Grid a Flexbox?
- [ ] Umím vytvořit responzivní layout bez frameworku?
- [ ] Znám všechny typy positioningu a kdy je použít?
- [ ] Umím pracovat s rem, em jednotkami?
- [ ] Vím, jak fungují media queries?
### JavaScript:
- [ ] Umím validovat formulář pomocí JavaScriptu?
- [ ] Rozumím event listenerům?
- [ ] Umím manipulovat s DOM?
- [ ] Znám základy RegEx?
- [ ] Umím vytvořit jednoduchou interaktivitu?
**Pokud máte většinu zaškrtlou, jste připraveni na Bootstrap!** 🎉
---
## 📈 Co dál po Bootstrap?
Po zvládnutí Bootstrap můžete pokračovat v:
- **Tailwind CSS** - utility-first framework
- **React** - JavaScript library pro UI
- **Vue.js** - progresivní JavaScript framework
- **SASS/SCSS** - CSS preprocessor
- **Node.js & Express** - backend JavaScript
- **Databáze** - MySQL, MongoDB
- **Full-stack projekty**
---
## 🙏 Acknowledgments
Projekty vytvořeny pro předmět **Webové Technologie** (WTL)
Cílová skupina: Studenti 3. ročníku IT
Generováno: 2025
---
**Hodně štěstí s projekty! Pokud máte jakékoliv dotazy, neváhejte se zeptat.** 🚀
---
## 📞 Kontakt na učitele
Při problémech nebo dotazech se obraťte na vyučujícího během konzultačních hodin nebo přes školní email.

21
AI_extra_material/ISP_PRG_pliva_1I.txt

@ -0,0 +1,21 @@
Ahoj,
posílám seznam témát které budeme dělat na programovaní, na náš kurzu na amos "PRG 1 - ročník 25/26" (máme společně s Radkem Rybákem, máme je rozdělené na skupiny)
moje skupina má studijní materiály z hodiny zde: https://git.asgard.odbornaskola.cz/skrabanek/1i_prg
Seznam témat:
- input, podminky, cykly
- ošetření chyb
- základní moduly (random, os, time, datetime)
- seznamy
- práce se soubory
- funkce
- pokročilá práce s funkcemi
- práce s textem a stringy
- instalace knihoven a pip
- CLI aplikace
- Objektově orientované programování (OOP)
- JSON & HTTP requests
Děkuji, snad jsem na nic nezpoměl
Jakub Škrabánek

428
AI_extra_material/ISP_WTL_3I.md

@ -0,0 +1,428 @@
# Individuální studijní plán - Webové technologie (WTL)
## 3. ročník IT - školní rok 2025/2026
---
## Základní informace
**Předmět:** Webové technologie (WTL)
**Ročník:** 3. ročník IT
**Vyučující:** [Jméno vyučujícího]
**Studijní materiály:** https://[odkaz na váš repozitář]
---
## Celkový přehled kurzu
Kurz Webových technologií je rozdělen do **dvou pololetí**:
### **1. pololetí (září - leden)**
- Základy HTML, CSS a JavaScriptu
- Responzivní webdesign
- Bootstrap framework
- Webová bezpečnost (XSS útoky)
- Komplexní frontend projekty
### **2. pololetí (únor - červen)**
- PHP základy
- Databáze (MySQL/MariaDB)
- Backend web development
- Webové aplikace (frontend + backend)
- Závěrečný projekt
---
## 📋 Seznam témat - 1. pololetí (Frontend)
### 1. Úvod do HTML
- Struktura HTML dokumentu
- Sémantické elementy (header, nav, main, footer, article, section, aside)
- Nadpisy, odstavce, seznamy
- Odkazy a obrázky
- Tabulky
- **Výstup:** Základní webová stránka
### 2. HTML Formuláře
- Formulářové elementy (input, textarea, select, button)
- Typy inputů (text, email, password, number, date, atd.)
- Atributy formulářů (required, placeholder, pattern)
- **Výstup:** Kontaktní formulář
### 3. Úvod do CSS
- Selektory (element, třída, ID)
- Box model (margin, padding, border)
- Barvy a pozadí
- Typografie (fonts, text styling)
- Pseudo-třídy (:hover, :visited, :focus)
- Gradienty
- **Výstup:** Nastylovaná webová stránka
### 4. CSS Layout
- Display property (block, inline, inline-block)
- Float a clear (legacy layout)
- Základy pozicování (static, relative, absolute, fixed)
- **Výstup:** Vícesloupcový layout
### 5. Úvod do JavaScriptu
- Proměnné (let, const, var)
- Datové typy (string, number, boolean, object, array)
- Operátory
- Podmínky (if, else, switch)
- Cykly (for, while)
- Funkce (function declaration, arrow functions)
- **Výstup:** Jednoduché JS skripty
### 6. JavaScript + HTML
- DOM (Document Object Model)
- Manipulace s HTML elementy
- querySelector, getElementById
- innerHTML, innerText, textContent
- Vytváření a odstraňování elementů
- **Výstup:** Dynamická webová stránka
### 7. JavaScript + CSS + DOM
- Manipulace s CSS přes JavaScript
- classList (add, remove, toggle)
- Změna stylů (style property)
- Event handling (onclick, addEventListener)
- **Výstup:** Interaktivní elementy (toggle, show/hide)
### 8. JavaScript Formuláře
- Event handling u formulářů
- Validace formulářů s JavaScriptem
- preventDefault()
- Získávání hodnot z formulářů
- **Výstup:** Validovaný formulář
### 9. Media Queries & Responzivní Design
- Viewport meta tag
- Media queries (@media)
- Breakpoints (mobile, tablet, desktop)
- Mobile-first přístup
- Responzivní obrázky
- **Výstup:** Responzivní webová stránka
### 10. CSS Flexbox
- display: flex
- flex-direction, justify-content, align-items
- flex-wrap, gap
- Flex položky (flex-grow, flex-shrink, flex-basis)
- **Výstup:** Flexbox layout
### 11. JSON & AJAX
- Formát JSON
- Fetch API
- Asynchronní JavaScript (promises, async/await)
- REST API základy
- **Výstup:** Aplikace načítající data z API
### 12. CSS Grid
- display: grid
- grid-template-columns, grid-template-rows
- gap, grid-gap
- Grid areas
- Rozdíl Grid vs Flexbox
- **Výstup:** Grid-based layout
---
## 🤖 AI Přípravné projekty (před Bootstrapem)
### AI 01 - CSS Grid & Responzivní Layout
- Pokročilé Grid techniky
- nth-child selektory
- Komplexní responzivní design
- **Hodnocení:** 10 bodů
### AI 02 - Sémantické HTML5 & CSS Positioning
- Sémantická struktura stránky
- Position: sticky, absolute, fixed, relative
- CSS jednotky (rem, em, vh, vw)
- **Hodnocení:** 15 bodů
### AI 03 - Pokročilá Validace Formulářů
- addEventListener
- Regulární výrazy (RegEx)
- Real-time validace
- Visual feedback
- **Hodnocení:** 20 bodů
### AI 04 - Komplexní Bootstrap Prep Projekt
- Kombinace všech předchozích konceptů
- CSS custom properties (variables)
- Pokročilé animace
- Modal, accordion implementace
- **Hodnocení:** 30 bodů
**Celkem za AI projekty: 75 bodů**
---
## 🎨 Bootstrap Framework
### 13. Bootstrap Úvod
- Instalace a setup Bootstrapu
- Bootstrap grid systém
- Container, row, col
- Utility třídy
### 14. Bootstrap Layout
- Responzivní breakpoints
- Grid options
- Flexbox utilities
- Spacing utilities (m-, p-)
### 15. Bootstrap Komponenty
- Buttons, badges, alerts
- Cards
- Navbar
- Forms (Bootstrap form styling)
- Tables
### 16. Bootstrap Carousel
- Carousel komponenta
- Indicators, controls
- Automatické přepínání
- **Výstup:** Fotogalerie s carousel
### 17. Bootstrap Modal
- Modal dialog
- Triggery pro modal
- Modal velikosti
- **Výstup:** Aplikace s modal dialogy
### 18. Bootstrap Form Validation
- Bootstrap validační třídy
- JavaScript validace s Bootstrapem
- Custom validation styles
- **Výstup:** Profesionální registrační formulář
---
## 🔒 Webová bezpečnost
### 19. XSS (Cross-Site Scripting) Demo
- Co je XSS útok
- Reflected XSS
- Stored XSS
- Prevence XSS útoků
- HTML sanitizace
- **Výstup:** Demo aplikace s XSS zranitelností a její oprava
---
## 🚀 Komplexní Frontend projekty
### 20. TODO List aplikace
- CRUD operace (Create, Read, Update, Delete)
- LocalStorage
- Bootstrap UI
- JavaScript manipulace s daty
- **Výstup:** Funkční TODO list
### 21. AJAX & API Integration
- Fetch API pokročile
- Práce s REST API
- Error handling
- Loading states
- **Výstup:** Aplikace pracující s externím API
---
## 📋 Seznam témat - 2. pololetí (Backend)
### 22. Úvod do PHP
- PHP syntaxe
- Proměnné a datové typy
- Podmínky a cykly
- Funkce v PHP
- Superglobals ($_GET, $_POST, $_SERVER)
### 23. PHP & Formuláře
- Zpracování formulářů (GET, POST)
- Validace na straně serveru
- Sanitizace vstupů
- CSRF ochrana
### 24. PHP & Soubory
- Čtení a zápis souborů
- Nahrávání souborů
- Práce s adresáři
- File permissions
### 25. Úvod do databází
- Relační databáze
- MySQL/MariaDB
- phpMyAdmin
- SQL příkazy (SELECT, INSERT, UPDATE, DELETE)
### 26. PHP & MySQL
- Připojení k databázi (mysqli, PDO)
- Prepared statements
- SQL injection prevence
- Databázové dotazy z PHP
### 27. Sessions & Cookies
- HTTP sessions
- Cookies
- Autentizace uživatelů
- Session security
### 28. Registrace & Login systém
- Uživatelská registrace
- Hash hesel (password_hash, password_verify)
- Login/logout funkcionalita
- Ochrana stránek (middleware)
### 29. CRUD Webová aplikace
- Create, Read, Update, Delete operace
- Databázové operace
- Admin rozhraní
- **Výstup:** Blog nebo e-shop backend
### 30. REST API v PHP
- JSON responses
- API endpoints
- HTTP metody (GET, POST, PUT, DELETE)
- API authentication
### 31. Závěrečný projekt
- Komplexní webová aplikace
- Frontend (HTML, CSS, JS, Bootstrap)
- Backend (PHP, MySQL)
- Funkční features (registrace, login, CRUD)
- Responzivní design
- **Hodnocení:** 100 bodů
---
## 🎯 Očekávané výstupy kurzu
Po dokončení kurzu by studenti měli umět:
### Frontend:
✅ Vytvořit sémanticky správnou HTML strukturu
✅ Nastylovat moderní responzivní web pomocí CSS
✅ Používat CSS Grid a Flexbox pro layout
✅ Psát čistý a efektivní JavaScript kód
✅ Manipulovat s DOM a zpracovávat eventy
✅ Validovat formuláře
✅ Pracovat s JSON a API pomocí Fetch
✅ Používat Bootstrap framework
✅ Rozumět základům webové bezpečnosti (XSS)
### Backend:
✅ Psát PHP skripty
✅ Zpracovávat formuláře na serveru
✅ Pracovat s MySQL databází
✅ Vytvořit registrační a přihlašovací systém
✅ Implementovat CRUD operace
✅ Zabezpečit webovou aplikaci (SQL injection, XSS, CSRF)
✅ Vytvořit jednoduché REST API
### Soft skills:
✅ Debugovat kód pomocí Developer Tools
✅ Používat Git pro verzování kódu
✅ Psát čitelný a udržovatelný kód
✅ Testovat aplikace v různých prohlížečích
✅ Pracovat samostatně i v týmu
---
## 📊 Hodnocení
### 1. pololetí:
- **AI projekty:** 75 bodů (AI 01-04)
- **Průběžné projekty:** 50 bodů
- **Aktivita a domácí úkoly:** 25 bodů
- **Test z frontend technologií:** 50 bodů
- **Celkem:** 200 bodů
### 2. pololetí:
- **PHP & MySQL projekty:** 50 bodů
- **Závěrečný projekt:** 100 bodů
- **Aktivita a domácí úkoly:** 25 bodů
- **Test z backend technologií:** 25 bodů
- **Celkem:** 200 bodů
### Celkové hodnocení za rok: 400 bodů
**Klasifikace:**
- 90-100% (360-400 bodů): Výborný (1)
- 75-89% (300-359 bodů): Chvalitebný (2)
- 60-74% (240-299 bodů): Dobrý (3)
- 45-59% (180-239 bodů): Dostatečný (4)
- 0-44% (0-179 bodů): Nedostatečný (5)
---
## 🛠️ Doporučené nástroje
### Editor:
- **Visual Studio Code** (primární doporučení)
- Extensions: Live Server, Prettier, Auto Rename Tag, CSS Peek
### Prohlížeče:
- **Google Chrome** (primární pro vývoj)
- Firefox, Edge (testování kompatibility)
- Chrome DevTools (F12) pro debugging
### Backend (2. pololetí):
- **XAMPP** nebo **WAMP** (Apache + MySQL + PHP)
- **phpMyAdmin** (správa databáze)
### Ostatní:
- **Git** pro verzování kódu
- **GitHub/GitLab** pro sdílení projektů
---
## 📚 Užitečné zdroje
### Dokumentace:
- [MDN Web Docs](https://developer.mozilla.org/) - HTML, CSS, JavaScript
- [Bootstrap dokumentace](https://getbootstrap.com/docs/)
- [PHP dokumentace](https://www.php.net/manual/en/)
- [MySQL dokumentace](https://dev.mysql.com/doc/)
### Online nástroje:
- [CodePen](https://codepen.io/) - Online playground
- [regex101.com](https://regex101.com/) - RegEx tester
- [Can I Use](https://caniuse.com/) - Browser compatibility
- [CSS-Tricks](https://css-tricks.com/) - CSS tutoriály
### Komunita:
- [Stack Overflow](https://stackoverflow.com/) - Q&A
- [CSS Tricks](https://css-tricks.com/)
- [JavaScript.info](https://javascript.info/)
---
## 📞 Kontakt
**Vyučující:** [Jméno vyučujícího]
**Email:** [email]
**Konzultační hodiny:** [časy]
**Repozitář:** [odkaz na Git repozitář]
---
## 📝 Poznámky
- Všechny projekty a úkoly budou zadávány průběžně během školního roku
- Studenti jsou povinni dodržovat termíny odevzdání
- Plagiátorství (kopírování kódu) bude sankcionováno
- Aktivní účast na hodinách je důležitá pro pochopení látky
- Doporučuje se pravidelné opakování a procvičování
- Studenti mohou využít konzultační hodiny pro pomoc s projekty
---
**Vytvořeno:** [datum]
**Předmět:** Webové Technologie (WTL)
**Cílová skupina:** 3. ročník IT
**Školní rok:** 2025/2026
---
*Tento studijní plán může být upraven na základě potřeb studentů a aktuálního pokroku ve výuce.*

31
AI_extra_material/ISP_WTL_3I.txt

@ -0,0 +1,31 @@
Ahoj,
posílám seznam témat které budeme dělat na Webových technologiích, na náš kurzu "WTL - 3. ročník 25/26"
studijní materiály z hodiny zde: [odkaz na repozitář]
Seznam témat - 1. pololetí (Frontend):
- úvod do HTML (struktura, sémantika, formuláře, tabulky)
- úvod do CSS (selektory, box model, barvy, typografie)
- CSS layout (float, positioning, flexbox, grid)
- media queries a responzivní design
- úvod do JavaScriptu (proměnné, podmínky, cykly, funkce)
- JavaScript + DOM (manipulace s HTML, querySelector, innerHTML)
- JavaScript eventy a validace formulářů
- JSON & Fetch API (asynchronní JavaScript, REST API)
- Bootstrap framework (grid systém, komponenty, utilities)
- Bootstrap pokročile (carousel, modal, form validation)
- webová bezpečnost (XSS útoky, prevence, sanitizace)
- komplexní frontend projekty (TODO list, AJAX aplikace)
Seznam témat - 2. pololetí (Backend):
- úvod do PHP (syntaxe, proměnné, podmínky, cykly, funkce)
- PHP formuláře (GET, POST, validace, sanitizace)
- PHP práce se soubory (čtení, zápis, upload)
- úvod do databází (MySQL, SQL příkazy)
- PHP & MySQL (připojení, dotazy, prepared statements)
- sessions & cookies (autentizace, zabezpečení)
- registrace & login systém (hash hesel, ochrana)
- závěrečný full-stack projekt (frontend + backend + databáze)
Děkuji, snad jsem na nic nezapomněl
[Tvoje jméno]

101
AI_extra_material/README.md

@ -0,0 +1,101 @@
# 📚 AI Extra Material - Doplňkové Studijní Materiály
## 🎯 Účel této složky
Tato složka obsahuje **doplňkové studijní materiály** pro hlubší pochopení pokročilých konceptů webového vývoje. Tyto materiály jsou navíc k základnímu učivu a slouží k samostudiu.
## 📂 Co složka obsahuje
### 🎓 AI Projekty (Základní verze v /AI složce)
Tato složka obsahuje **duplikáty AI projektů** z hlavní složky `/AI`. Jsou zde pro pohodlný přístup k materiálům.
- **ai_01_grid_responsive** - CSS Grid & Responzivní Layout
- **ai_02_semantic_portfolio** - Sémantické HTML5 & CSS Positioning
- **ai_03_form_validation** - Pokročilá Validace Formulářů s JavaScript
- **ai_04_prep_bootstrap** - Komplexní Bootstrap Prep Projekt
### 📋 Informační Soubory
- **AI_PROJEKTY_README.md** - Přehled všech AI projektů
- **UCITEL_INFO.md** - Informace pro učitele o projektech, hodnocení, harmonogramu
- **ISP_WTL_3I.md** - Individuální studijní plán (ISP)
- **ISP_WTL_3I.txt** - ISP v textové podobě
### 🚀 Bootstrap Doplňkové Projekty
#### 18_form_validation_bootstrap
Ukázka validace formulářů s Bootstrap 5.
- Bootstrap validační třídy
- Custom validace s JavaScriptem
- Visual feedback pro uživatele
- Propojení s Bootstrap styly
**Kdy použít:** Pro pochopení, jak Bootstrap řeší validaci formulářů "out of the box".
#### 18a_form_xss_demo
**BEZPEČNOSTNÍ DEMO** - ukázka XSS (Cross-Site Scripting) zranitelnosti.
- Demonstrace nebezpečného kódu
- Jak vznikají XSS útoky
- Jak se bránit (sanitizace inputů)
- Best practices pro bezpečnost
**⚠️ VAROVÁNÍ:** Tento kód je záměrně zranitelný pro výukové účely. **NIKDY** nepoužívejte tento přístup v produkčním kódu!
## 🎓 Jak pracovat s těmito materiály
### Pro studenty:
1. **Nejdříve dokončete základní AI projekty** v hlavní složce `/AI`
2. **Pokud chcete víc:** Projděte si tyto doplňkové materiály
3. **Bootstrap validace:** Po dokončení AI 03, prozkoumejte `18_form_validation_bootstrap`
4. **Bezpečnost:** Po práci s formuláři si prostudujte `18a_form_xss_demo`
### Pro učitele:
- Přečtěte si **UCITEL_INFO.md** pro detailní informace o projektech
- **AI_PROJEKTY_README.md** obsahuje přehled všech AI projektů
- **ISP** soubory obsahují studijní plán
## 🔗 Návaznost na hlavní kurz
| Základní kurz | Extra Material | Proč je užitečný |
|---------------|----------------|------------------|
| 08_js_form | 18_form_validation_bootstrap | Ukáže Bootstrap přístup k validaci |
| AI 03 | 18a_form_xss_demo | Bezpečnostní aspekty formulářů |
| 13-17 Bootstrap | AI projekty (duplikáty) | Opakování před Bootstrapem |
## 💡 Doporučené Pořadí Studia
1. **Základní kurz** (01-20) - absolvujte nejdříve
2. **AI projekty** v hlavní složce `/AI` - praktické projekty
3. **Bootstrap validace** (`18_form_validation_bootstrap`) - po Bootstrap lekcích
4. **XSS Demo** (`18a_form_xss_demo`) - pro pochopení bezpečnosti
5. **ISP materiály** - pro samostudium dle potřeby
## ⚠️ Důležité poznámky
- ✅ Tyto materiály jsou **nepovinné** - jsou navíc k základnímu kurzu
- ✅ Projekty v této složce jsou **duplikáty** - hlavní verze jsou v `/AI`
- ⚠️ **XSS Demo** je záměrně zranitelný - slouží pouze k výukovým účelům
- 📚 **UCITEL_INFO.md** obsahuje hodnocení a harmonogram pro učitele
## 📖 Hlavní AI Projekty
**POZOR:** Hlavní verze AI projektů jsou v kořenové složce **`/AI`**!
Pro práci na projektech používejte soubory z `/AI`, ne z této složky. Tato složka slouží jako archiv a reference.
## 🎯 Cíle Extra Materiálů
Po prostudování těchto materiálů budete:
- ✅ Rozumět Bootstrap validaci formulářů
- ✅ Vědět, jak se bránit XSS útokům
- ✅ Mít hlubší pochopení bezpečnosti webových aplikací
- ✅ Umět propojit Bootstrap s custom validací
---
**Hodně štěstí s dalším studiem! 📚✨**
*Tyto materiály rozšiřují základní kurz a poskytují hlubší vhled do pokročilých témat.*

351
AI_extra_material/UCITEL_INFO.md

@ -0,0 +1,351 @@
# 👨‍🏫 Informace pro učitele - AI Projekty
## 📊 Analýza současného stavu studentů
### ✅ Co studenti již zvládají:
**HTML:**
- Základní struktura, nadpisy (h1-h6)
- Odkazy, obrázky
- Formuláře (input, textarea, select, button)
- Tabulky a seznamy
- Částečně sémantické elementy (header, footer, aside, article)
**CSS:**
- Základní selektory (element, třída, ID)
- Box model (margin, padding, border)
- Pseudo-třídy (:hover, :visited)
- Gradienty a transitions
- Flexbox (základy)
- Media queries (základy)
- Float-based layout (starší přístup)
**JavaScript:**
- Proměnné (let, const, var)
- Datové typy a objekty
- Podmínky a cykly
- Funkce
- DOM manipulace (getElementById, innerHTML, innerText)
- Event handling (inline onclick)
- JSON a Fetch API
### ⚠️ Co chybí před Bootstrapem:
**KRITICKÉ mezery:**
1. **CSS Grid** - chybí úplně
2. **addEventListener** - používají jen inline onclick
3. **Pokročilé CSS selektory** (nth-child, ::before, ::after)
4. **CSS jednotky** - používají jen px, ne rem/em/vh/vw
5. **Position: sticky a absolute** - nepoužito
6. **Form validace s JS** - jen základní
**DOPORUČUJI doplnit:**
7. **CSS proměnné** (custom properties)
8. **Pokročilé animace**
9. **Scroll efekty**
10. **Mobile-first přístup**
---
## 🎯 Účel AI projektů
Projekty byly navrženy tak, aby:
1. **Systematicky doplnily mezery** v znalostech
2. **Postupně zvyšovaly náročnost** (od jednoduchého po komplexní)
3. **Připravily na Bootstrap filozofii** (grid systém, utility třídy, komponenty)
4. **Poskytly praktickou zkušenost** s real-world projekty
---
## 📋 Přehled projektů pro učitele
### AI 01 - CSS Grid & Responzivní Layout
**Čas:** 1-2 vyučovací hodiny
**Obtížnost:** Střední
**Cíl:** Naučit CSS Grid před Bootstrap grid systémem
**Klíčové koncepty:**
- `display: grid`
- `grid-template-columns`
- `gap`
- Pokročilé selektory (nth-child)
- Media queries pro responzivitu
**Výstup:** Responzivní galerie s 9 položkami
---
### AI 02 - Sémantické HTML5 & CSS Positioning
**Čas:** 2-3 vyučovací hodiny
**Obtížnost:** Náročné
**Cíl:** Sémantický HTML5 a všechny typy positioning
**Klíčové koncepty:**
- Sémantické elementy (nav, main, section, article, aside)
- Position: fixed, sticky, relative, absolute
- CSS jednotky: rem, em, vh, vw
- Správná struktura moderní stránky
**Výstup:** Portfolio stránka s fixní navigací a sticky sidebar
---
### AI 03 - Pokročilá Validace Formulářů
**Čas:** 2-3 vyučovací hodiny
**Obtížnost:** Náročné
**Cíl:** Real-time validace s JS (Bootstrap má validační třídy)
**Klíčové koncepty:**
- `addEventListener` místo inline events
- RegEx pro validaci
- DOM manipulace (classList)
- Real-time feedback
- UX best practices
**Výstup:** Registrační formulář s kompletní validací
---
### AI 04 - Komplexní Bootstrap Prep Projekt
**Čas:** 4-6 vyučovacích hodin (nebo domácí práce)
**Obtížnost:** Velmi náročné
**Cíl:** Komplexní projekt kombinující všechny koncepty
**Klíčové koncepty:**
- Všechny předchozí koncepty
- CSS proměnné
- Scroll efekty
- Modal, accordion
- Mobile-first
**Výstup:** Plně funkční landing page
---
## 📅 Doporučený harmonogram
### Varianta A - Intenzivní (2 týdny)
```
Týden 1:
Po: AI 01 + AI 02 začátek
St: AI 02 dokončení + AI 03 začátek
Pá: AI 03 dokončení
Týden 2:
Po-Pá: AI 04 (průběžně)
Pá: Prezentace AI 04
Týden 3:
Bootstrap start!
```
### Varianta B - Standardní (3 týdny)
```
Týden 1:
Lekce 1: AI 01
Lekce 2: AI 02
Týden 2:
Lekce 1: AI 03 část 1
Lekce 2: AI 03 část 2
Týden 3:
Lekce 1-2: AI 04 (práce ve třídě)
DÚ: Dokončení AI 04
Týden 4:
Bootstrap start!
```
### Varianta C - Volnočasová (4 týdny)
```
Týden 1: AI 01
Týden 2: AI 02
Týden 3: AI 03
Týden 4: AI 04
Týden 5: Bootstrap start!
```
---
## 🎓 Hodnocení projektů
### AI 01 (10 bodů)
- HTML struktura (2b)
- CSS Grid implementace (3b)
- Media queries (2b)
- Pokročilé selektory (2b)
- Responzivita (1b)
### AI 02 (15 bodů)
- Sémantická struktura (4b)
- Position: fixed, sticky (3b)
- Position: relative, absolute (3b)
- CSS jednotky (rem, em, vh) (2b)
- Responzivita (3b)
### AI 03 (20 bodů)
- addEventListener použití (4b)
- Validační funkce (6b)
- RegEx implementace (3b)
- Visual feedback (4b)
- Submit handling (3b)
### AI 04 (30 bodů)
- HTML struktura (5b)
- CSS Grid & Flexbox (6b)
- Positioning (4b)
- JavaScript interaktivita (6b)
- Responzivita (4b)
- Design & UX (3b)
- Clean code (2b)
**Celkem: 75 bodů**
---
## 💡 Tips pro učitele
### Při výuce AI 01:
1. Začněte s vysvětlením rozdílu Grid vs Flexbox
2. Ukažte Chrome DevTools - Grid overlay
3. Procvičte nth-child na příkladech
4. Zdůrazněte mobile-first přístup
### Při výuce AI 02:
1. Narýsujte positioning na tabuli (fixed, sticky, relative, absolute)
2. Ukažte proč používat rem místo px
3. Vysvětlete z-index context
4. Zdůrazněte důležitost sémantiky pro SEO
### Při výuce AI 03:
1. Živě ukažte addEventListener vs onclick
2. Procvičte RegEx na regex101.com
3. Vysvětlete event.preventDefault()
4. Ukažte console.log() debugging
### Při výuce AI 04:
1. Nechte studenty pracovat samostatně
2. Buďte dostupní pro konzultace
3. Povzbuďte kreativitu
4. Na konci nechte studenty prezentovat
---
## 🔧 Troubleshooting - Časté problémy studentů
### CSS Grid:
**Problem:** "Grid nefunguje"
**Řešení:** Zkontrolujte `display: grid` na kontejneru, ne na položkách
### Positioning:
**Problem:** "Absolute element je mimo stránku"
**Řešení:** Parent musí mít `position: relative`
### addEventListener:
**Problem:** "Funkce se volá hned při načtení"
**Řešení:** Nepsat `validateName()` ale jen `validateName` (bez závorek)
### RegEx:
**Problem:** "RegEx nefunguje"
**Řešení:** Otestujte na regex101.com, možná chybí escape znaky
### Media queries:
**Problem:** "Responzivita nefunguje"
**Řešení:** Zkontrolujte `<meta name="viewport">` v head
---
## 📊 Očekávané výsledky
Po dokončení všech projektů by studenti měli:
### Znát:
✅ Rozdíl mezi Grid a Flexbox a kdy co použít
✅ Všechny typy CSS positioning
✅ Jak vytvořit responzivní layout bez frameworku
✅ Jak validovat formuláře v JavaScriptu
✅ addEventListener a event handling
✅ Základy RegEx
✅ Mobile-first přístup
### Umět:
✅ Vytvořit komplexní responzivní stránku
✅ Implementovat interaktivní funkce
✅ Validovat formuláře s visual feedbackem
✅ Používat pokročilé CSS selektory
✅ Debugovat pomocí Developer Tools
### Být připraveni na:
✅ Bootstrap grid systém (pochopí jak funguje)
✅ Bootstrap komponenty (pochopí co řeší)
✅ Bootstrap utilities (pochopí proč existují)
✅ Přizpůsobení frameworku vlastním potřebám
---
## 🎯 Přechod na Bootstrap
Po dokončení AI projektů vysvětlete studentům:
1. **Co Bootstrap řeší:**
- "Vzpomínáte, jak jste v AI 01 vytvářeli grid systém? Bootstrap to má už hotové."
- "Vzpomínáte na validaci formuláře v AI 03? Bootstrap má validační třídy."
2. **Proč jsme to dělali ručně:**
- "Teď rozumíte, co Bootstrap dělá pod kapotou."
- "Když něco nebude fungovat, budete vědět proč."
- "Umíte to bez frameworku = jste lepší developer."
3. **Kdy použít Bootstrap vs custom CSS:**
- Bootstrap: Rychlé prototypování, standardní projekty
- Custom: Unikátní design, optimalizace, portfolio projekty
---
## 📞 Podpora
Pokud najdete chyby v projektech nebo máte návrhy na zlepšení, kontaktujte:
- GitHub Issues v repozitáři
- Email učiteli
- Během konzultačních hodin
---
## 📝 Poznámky k implementaci
### Struktura souborů:
```
ai_XX_project_name/
├── ZADANI.md # Detailní zadání pro studenty
├── index.html # Startovací HTML (s TODO komentáři)
├── style.css # CSS šablona (s TODO komentáři)
├── script.js # JS šablona (s TODO komentáři)
├── reseni.html # Kompletní řešení
├── reseni.css # CSS s podrobnými komentáři
└── reseni.js # JS s podrobnými komentáři
```
### Filozofie:
- **Startovací soubory** obsahují TODO a strukturu
- **Řešení** obsahuje detailní komentáře vysvětlující každý řádek
- **ZADANI.md** obsahuje learning objectives a užitečné odkazy
---
## 🎉 Závěr
Tyto projekty důkladně připraví studenty na Bootstrap. Investovaný čas se vrátí v:
- Lepším pochopení frameworku
- Schopnosti přizpůsobení
- Debugovacích dovednostech
- Celkově lepších web development skills
**Hodně štěstí při výuce!** 🚀
---
Vytvořeno: 24. října 2025
Předmět: Webové Technologie (WTL)
Cílová skupina: 3. ročník IT

158
AI_extra_material/ai_01_grid_responsive/README.md

@ -0,0 +1,158 @@
# AI 01 - CSS Grid & Responzivní Layout
## 🎯 Cíl projektu
Naučit se pracovat s **CSS Grid systémem** a **pokročilými CSS selektory**, které jsou důležité pro pochopení Bootstrap grid systému.
## 📋 Co se naučíte
- **CSS Grid základy** - `display: grid`, `grid-template-columns`
- **Grid gaps** - mezery mezi položkami
- **Responzivní grid** s media queries
- **Pokročilé CSS selektory** - `:nth-child()`, `:first-child`, `:last-child`
- **CSS transformace** - `scale()` při hover
- **Grid template areas** - pojmenované oblasti
## 📂 Soubory v projektu
- **ZADANI.md** - detailní zadání projektu s požadavky
- **index.html** - startovací HTML soubor (s TODO komentáři pro vás)
- **style.css** - CSS šablona (s TODO komentáři)
- **reseni.html** - kompletní řešení (podívejte se, když zaseknete)
- **reseni.css** - CSS s podrobnými komentáři vysvětlující každý řádek
## 🚀 Jak pracovat s projektem
### Krok 1: Přečtěte si ZADANI.md
- Otevřete `ZADANI.md` a přečtěte si celé zadání
- Pochopte, co máte vytvořit
- Prohlédněte si ukázky kódu
### Krok 2: Začněte s index.html a style.css
- Otevřete `index.html` a `style.css`
- Najděte **TODO komentáře** - to jsou místa, kde máte psát kód
- Postupujte podle TODO instrukcí
### Krok 3: Testujte responzivitu
1. Otevřete `index.html` v prohlížeči
2. Otevřete Developer Tools (F12)
3. Zapněte Device Toolbar (Ctrl+Shift+M)
4. Testujte různé velikosti:
- Desktop (> 768px) - 3 sloupce
- Tablet (768px) - 2 sloupce
- Mobil (480px) - 1 sloupec
### Krok 4: Když se zaseknete
- Podívejte se do `reseni.css` - jsou tam podrobné komentáře
- Zkuste pochopit PROČ to funguje, ne jen zkopírovat
- Porovnejte své řešení s hotovým
## 💡 Klíčové koncepty
### CSS Grid pattern:
```css
/* Kontejner */
.grid-container {
display: grid; /* MUSÍ BÝT! */
grid-template-columns: repeat(3, 1fr); /* 3 sloupce */
gap: 20px; /* mezery */
}
/* Položky se umístí automaticky */
.grid-item {
background-color: lightblue;
padding: 20px;
}
```
### Responzivní breakpointy:
```css
/* Desktop (výchozí) - 3 sloupce */
.grid-container {
grid-template-columns: repeat(3, 1fr);
}
/* Tablet */
@media (max-width: 768px) {
.grid-container {
grid-template-columns: repeat(2, 1fr);
}
}
/* Mobil */
@media (max-width: 480px) {
.grid-container {
grid-template-columns: 1fr;
}
}
```
### Pokročilé selektory:
```css
/* Liché položky (1, 3, 5, ...) */
.grid-item:nth-child(odd) {
background-color: lightblue;
}
/* Sudé položky (2, 4, 6, ...) */
.grid-item:nth-child(even) {
background-color: lightgreen;
}
/* První položka */
.grid-item:first-child {
background-color: gold;
}
/* Poslední položka */
.grid-item:last-child {
background-color: pink;
}
/* Hover efekt */
.grid-item:hover {
transform: scale(1.05); /* zvětší o 5% */
cursor: pointer;
}
```
## ⚠️ Časté chyby
❌ **Grid nefunguje**
→ Zapomněli jste `display: grid` na kontejneru
❌ **Responzivita nefunguje**
→ Chybí `<meta name="viewport">` v `<head>`
❌ **nth-child nefunguje**
→ Zkontrolujte syntax: `:nth-child(odd)` ne `.nth-child(odd)`
❌ **Gap nefunguje**
`gap` funguje pouze v grid/flex containeru
## 🎓 Hodnocení (10 bodů)
- **HTML struktura** (2b) - správná struktura, 9+ položek
- **CSS Grid implementace** (3b) - grid-template-columns, gap
- **Media queries** (2b) - 3 breakpointy (desktop, tablet, mobil)
- **Pokročilé selektory** (2b) - nth-child, first/last-child, hover
- **Responzivita** (1b) - funguje na všech zařízeních
## 🔗 Užitečné odkazy
- [CSS Grid Guide - CSS Tricks](https://css-tricks.com/snippets/css/complete-guide-grid/)
- [nth-child selector - MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child)
- [CSS Transform - MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/transform)
## ⏱️ Odhadovaný čas
**45-60 minut**
## 🎯 Po dokončení
Po dokončení tohoto projektu budete rozumět:
- Jak funguje CSS Grid (základ pro Bootstrap grid)
- Jak vytvořit responzivní layout bez frameworku
- Pokročilé CSS selektory
➡️ **Další projekt:** AI 02 - Sémantické HTML5 & CSS Positioning

49
AI_extra_material/ai_01_grid_responsive/ZADANI.md

@ -0,0 +1,49 @@
# AI 01 - CSS Grid & Responzivní Layout
## 🎯 Cíl projektu
Naučit se pracovat s CSS Grid systémem a pokročilými CSS selektory, které jsou důležité pro pochopení Bootstrap grid systému.
## 📝 Zadání
Vytvořte responzivní галерию obrázků s následujícími vlastnostmi:
### HTML požadavky:
1. Vytvořte stránku s hlavičkou (h1) "Galerie Obrázků"
2. Vytvořte grid kontejner s minimálně 9 položkami (divy s třídou "grid-item")
3. Každá položka má obsahovat:
- Číslo položky (h3)
- Text "Obsah položky" (p)
- Barvu pozadí (přes CSS)
### CSS požadavky:
#### Grid Layout:
- Použijte `display: grid`
- Na desktopu: 3 sloupce se stejnou šířkou
- Na tabletu (max-width: 768px): 2 sloupce
- Na mobilu (max-width: 480px): 1 sloupec
- Mezery mezi položkami: 20px
#### Pokročilé selektory:
Použijte tyto selektory pro obarvení položek:
- `.grid-item:nth-child(odd)` - liché položky -> světle modrá
- `.grid-item:nth-child(even)` - sudé položky -> světle zelená
- `.grid-item:first-child` - první položka -> zlatá
- `.grid-item:last-child` - poslední položka -> růžová
- `.grid-item:hover` - při najetí myší -> ztmavnout + zvětšit o 5%
#### Extra výzva:
- Použijte `grid-template-areas` pro vytvoření speciálního layoutu, kde první položka zabírá 2 sloupce
## 💡 Co se naučíte:
- CSS Grid základy (display: grid, grid-template-columns)
- Grid gaps (mezery)
- Responzivní grid s media queries
- Pokročilé CSS selektory (nth-child, first-child, last-child)
- CSS transformace (scale při hover)
## 🔗 Užitečné odkazy:
- CSS Grid Guide: https://css-tricks.com/snippets/css/complete-guide-grid/
- nth-child selector: https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child
## ⏱️ Odhadovaný čas: 45-60 minut

18
AI_extra_material/ai_01_grid_responsive/index.html

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 01 - CSS Grid Galerie</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Galerie Obrázků</h1>
<!-- TODO: Zde začněte pracovat -->
<!-- Vytvořte kontejner s třídou "grid-container" -->
<!-- Vytvořte 9 divů s třídou "grid-item" -->
<!-- Každý div má obsahovat h3 s číslem a p s textem -->
</body>
</html>

151
AI_extra_material/ai_01_grid_responsive/reseni.css

@ -0,0 +1,151 @@
/* AI 01 - CSS Grid & Responzivní Layout - ŘEŠENÍ */
/* Základní styly pro body */
body {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
padding: 20px;
background-color: #f0f0f0;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
}
/* Grid kontejner */
.grid-container {
/* Display grid aktivuje grid layout */
display: grid;
/* Vytvoří 3 sloupce se stejnou šířkou (1fr = 1 fraction/část) */
grid-template-columns: 1fr 1fr 1fr;
/* Alternativně: repeat(3, 1fr) - opakuje 1fr třikrát */
/* Gap vytváří mezery mezi grid položkami */
gap: 20px;
/* Alternativně: grid-gap: 20px; (starší syntax) */
/* Maximální šířka kontejneru */
max-width: 1200px;
margin: 0 auto;
}
/* Styling jednotlivých grid položek */
.grid-item {
/* Základní styling */
background-color: white;
padding: 30px;
border-radius: 10px;
text-align: center;
/* Box shadow pro hezčí vzhled */
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
/* Transition pro plynulé animace */
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.grid-item h3 {
margin-top: 0;
color: #333;
}
.grid-item p {
color: #666;
margin-bottom: 0;
}
/* POKROČILÉ SELEKTORY */
/* nth-child(odd) = liché položky (1, 3, 5, 7, 9) */
.grid-item:nth-child(odd) {
background-color: #e3f2fd; /* světle modrá */
}
/* nth-child(even) = sudé položky (2, 4, 6, 8) */
.grid-item:nth-child(even) {
background-color: #e8f5e9; /* světle zelená */
}
/* first-child = první položka */
.grid-item:first-child {
background-color: #ffd700; /* zlatá */
/* Můžeme použít grid-column pro natažení přes 2 sloupce */
grid-column: span 2;
}
/* last-child = poslední položka */
.grid-item:last-child {
background-color: #ffb6c1; /* růžová */
}
/* Hover efekt - při najetí myší */
.grid-item:hover {
/* Transform scale zvětší element o 5% (1.05 = 105%) */
transform: scale(1.05);
/* Větší shadow při hover */
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
/* Můžeme také změnit kurzor */
cursor: pointer;
}
/* MEDIA QUERIES - Responzivita */
/* Tablet - maximální šířka 768px */
@media only screen and (max-width: 768px) {
.grid-container {
/* Na tabletu jen 2 sloupce */
grid-template-columns: 1fr 1fr;
/* Alternativně: repeat(2, 1fr) */
}
/* První položka už nezabírá 2 sloupce na tabletu */
.grid-item:first-child {
grid-column: span 1;
}
}
/* Mobil - maximální šířka 480px */
@media only screen and (max-width: 480px) {
body {
padding: 10px;
}
.grid-container {
/* Na mobilu jen 1 sloupec */
grid-template-columns: 1fr;
/* Menší gap na mobilu */
gap: 15px;
}
.grid-item {
/* Menší padding na mobilu */
padding: 20px;
}
h1 {
font-size: 24px;
}
}
/* BONUS: Další užitečné selektory */
/* Každá třetí položka (3, 6, 9) */
/* .grid-item:nth-child(3n) {
border: 3px solid #ff6b6b;
} */
/* Všechny položky kromě první */
/* .grid-item:not(:first-child) {
opacity: 0.9;
} */
/* První 3 položky */
/* .grid-item:nth-child(-n+3) {
font-weight: bold;
} */

51
AI_extra_material/ai_01_grid_responsive/reseni.html

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 01 - CSS Grid Galerie - ŘEŠENÍ</title>
<link rel="stylesheet" href="reseni.css">
</head>
<body>
<h1>Galerie Obrázků</h1>
<div class="grid-container">
<div class="grid-item">
<h3>Položka 1</h3>
<p>Obsah položky</p>
</div>
<div class="grid-item">
<h3>Položka 2</h3>
<p>Obsah položky</p>
</div>
<div class="grid-item">
<h3>Položka 3</h3>
<p>Obsah položky</p>
</div>
<div class="grid-item">
<h3>Položka 4</h3>
<p>Obsah položky</p>
</div>
<div class="grid-item">
<h3>Položka 5</h3>
<p>Obsah položky</p>
</div>
<div class="grid-item">
<h3>Položka 6</h3>
<p>Obsah položky</p>
</div>
<div class="grid-item">
<h3>Položka 7</h3>
<p>Obsah položky</p>
</div>
<div class="grid-item">
<h3>Položka 8</h3>
<p>Obsah položky</p>
</div>
<div class="grid-item">
<h3>Položka 9</h3>
<p>Obsah položky</p>
</div>
</div>
</body>
</html>

50
AI_extra_material/ai_01_grid_responsive/style.css

@ -0,0 +1,50 @@
/* AI 01 - CSS Grid & Responzivní Layout */
/* Základní styly pro body */
body {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
padding: 20px;
background-color: #f0f0f0;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
}
/* TODO: Zde začněte pracovat s Grid */
/* 1. Vytvořte .grid-container s display: grid */
/* 2. Nastavte grid-template-columns pro 3 sloupce (desktop) */
/* 3. Nastavte gap (mezery) mezi položkami na 20px */
/* 4. Nastylujte .grid-item */
/* 5. Použijte pokročilé selektory pro obarvení */
/* .grid-item:nth-child(odd) - liché položky */
/* .grid-item:nth-child(even) - sudé položky */
/* .grid-item:first-child - první položka */
/* .grid-item:last-child - poslední položka */
/* .grid-item:hover - hover efekt */
/* 6. Media query pro tablet (max-width: 768px) - 2 sloupce */
/* 7. Media query pro mobil (max-width: 480px) - 1 sloupec */

221
AI_extra_material/ai_02_semantic_portfolio/README.md

@ -0,0 +1,221 @@
# AI 02 - Sémantické HTML5 & CSS Positioning
## 🎯 Cíl projektu
Naučit se používat **sémantické HTML5 elementy** a **CSS positioning** (absolute, relative, fixed, sticky), které jsou důležité pro moderní webový vývoj a Bootstrap.
## 📋 Co se naučíte
- **Sémantické HTML5 elementy** - `<nav>`, `<main>`, `<section>`, `<article>`, `<aside>`, `<footer>`
- **CSS Positioning** - `fixed`, `sticky`, `relative`, `absolute`
- **CSS jednotky** - `rem`, `em`, `vh`, `vw` (ne jen `px`!)
- **Strukturu moderní webové stránky**
- **Z-index** - vrstvení elementů
## 📂 Soubory v projektu
- **ZADANI.md** - detailní zadání projektu
- **index.html** - startovací HTML (s TODO komentáři)
- **style.css** - CSS šablona (s TODO komentáři)
- **reseni.html** - kompletní řešení
- **reseni.css** - CSS s podrobnými komentáři
## 🚀 Jak pracovat s projektem
### Krok 1: Přečtěte si ZADANI.md
- Pochopte, jaké elementy máte vytvořit
- Projděte si požadavky na positioning
### Krok 2: Vytvořte strukturu stránky
Vytvořte **portfolio stránku** s těmito sekcemi:
1. **`<nav>`** - fixní navigace nahoře
2. **`<header>`** - úvodní sekce (hero)
3. **`<main>`** s `<section>` elementy:
- O mně
- Projekty (s `<article>` elementy)
- Kontakt
4. **`<aside>`** - sticky boční panel
5. **`<footer>`** - zápatí
### Krok 3: Aplikujte CSS Positioning
**Fixed navigace:**
```css
nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 1000; /* nad ostatními elementy */
}
```
**Sticky aside:**
```css
aside {
position: sticky;
top: 100px; /* od vrcholu po scrollování */
}
```
**Absolute badge:**
```css
.project {
position: relative; /* kontejner */
}
.badge {
position: absolute;
top: 10px;
right: 10px;
}
```
### Krok 4: Použijte moderní jednotky
```css
/* ❌ Staré (pouze px) */
font-size: 16px;
padding: 20px;
height: 600px;
/* ✅ Moderní (rem, em, vh) */
font-size: 1rem; /* 16px (skaluje s root) */
padding: 1.25rem; /* 20px */
height: 60vh; /* 60% výšky viewportu */
```
## 💡 Klíčové koncepty
### Sémantické HTML5 elementy:
```html
<!-- ✅ SPRÁVNĚ - sémantické -->
<nav>
<a href="#home">Domů</a>
</nav>
<main>
<section id="about">
<h2>O mně</h2>
<article>...</article>
</section>
</main>
<aside>Boční panel</aside>
<footer>© 2025</footer>
<!-- ❌ ŠPATNĚ - nesémantické -->
<div class="nav">
<a href="#home">Domů</a>
</div>
<div class="main">
<div class="section">...</div>
</div>
```
### CSS Positioning:
**Static (výchozí):**
- Normální tok dokumentu
- Nelze posunout pomocí top/left/right/bottom
**Relative:**
- Relativní k původní pozici
- Nezabírá místo v místě posunutí
```css
.element {
position: relative;
top: 20px; /* posune se 20px dolů od původní pozice */
}
```
**Absolute:**
- Absolutní k nejbližšímu pozicovanému rodiči
- Vyjmut z normálního toku
```css
.parent {
position: relative; /* !! důležité !! */
}
.child {
position: absolute;
top: 0;
right: 0;
}
```
**Fixed:**
- Fixní k viewportu
- Zůstává na místě při scrollování
```css
.navbar {
position: fixed;
top: 0;
width: 100%;
}
```
**Sticky:**
- Kombinace relative a fixed
- Sticky když dojedete na určitou pozici
```css
.sidebar {
position: sticky;
top: 20px; /* zůstane 20px od vrcholu */
}
```
### CSS Jednotky:
| Jednotka | Popis | Použití |
|----------|-------|---------|
| `px` | Pixel (absolutní) | Borders, malé hodnoty |
| `rem` | Relativní k root font-size | Font sizes, paddingy |
| `em` | Relativní k parent font-size | Specifické případy |
| `%` | Procenta z parenta | Šířky, výšky |
| `vh` | 1% výšky viewportu | Full-screen sekce |
| `vw` | 1% šířky viewportu | Responzivní šířky |
## ⚠️ Časté chyby
❌ **Absolute element není kde má být**
→ Zapomněli jste `position: relative` na rodiče
❌ **Fixed navigace překrývá obsah**
→ Přidejte `padding-top` na body nebo main
❌ **Sticky nefunguje**
→ Zkontrolujte, že má rodič dostatek výšky na scrollování
❌ **Z-index nefunguje**
→ Funguje pouze na pozicovaných elementech (ne static)
## 🎓 Hodnocení (15 bodů)
- **Sémantická struktura** (4b) - správné použití nav, main, section, article, aside, footer
- **Position: fixed, sticky** (3b) - fixní navigace, sticky aside
- **Position: relative, absolute** (3b) - badge na projektu
- **CSS jednotky (rem, em, vh)** (2b) - použití místo px
- **Responzivita** (3b) - aside zmizí na mobilu, funguje na všech zařízeních
## 🔗 Užitečné odkazy
- [HTML5 Semantic Elements - W3Schools](https://www.w3schools.com/html/html5_semantic_elements.asp)
- [CSS Position - CSS Tricks](https://css-tricks.com/almanac/properties/p/position/)
- [CSS Units - MDN](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units)
## ⏱️ Odhadovaný čas
**60-90 minut**
## 🎯 Po dokončení
Po dokončení tohoto projektu budete rozumět:
- Sémantické HTML5 (důležité pro SEO a přístupnost)
- Všem typům CSS positioning
- Moderním CSS jednotkám (rem, vh, vw)
- Jak vytvořit sticky/fixed elementy
➡️ **Další projekt:** AI 03 - Pokročilá Validace Formulářů s JavaScript

67
AI_extra_material/ai_02_semantic_portfolio/ZADANI.md

@ -0,0 +1,67 @@
# AI 02 - Sémantické HTML5 & CSS Positioning
## 🎯 Cíl projektu
Naučit se používat sémantické HTML5 elementy a CSS positioning (absolute, relative, fixed, sticky), které jsou důležité pro moderní webový vývoj a Bootstrap.
## 📝 Zadání
Vytvořte jednoduchou osobní portfolio stránku s následujícími sekcemi:
### HTML požadavky - Použijte SÉMANTICKÉ elementy:
1. **`<nav>`** - Navigační menu (fixní nahoře)
- Logo (h2)
- 4 odkazy: Domů, O mně, Projekty, Kontakt
2. **`<header>`** - Úvodní sekce
- Hlavní nadpis s vaším jménem (h1)
- Podnadpis s profesí (p)
- Tlačítko "Více o mně"
3. **`<main>`** - Hlavní obsah stránky obsahující:
**`<section id="about">`** - O mně
- Nadpis (h2)
- 2-3 odstavce textu (p)
- Obrázek (placeholder: https://via.placeholder.com/300)
**`<section id="projects">`** - Projekty
- Nadpis (h2)
- 3x `<article>` s projekty
- Každý article má: h3 (název), p (popis), obrázek
**`<section id="contact">`** - Kontakt
- Nadpis (h2)
- Formulář (jméno, email, zpráva, tlačítko)
4. **`<footer>`** - Zápatí
- Copyright text
- Sociální sítě odkazy
5. **`<aside>`** - Boční panel (sticky)
- "Rychlé info"
- Email, Telefon, Lokace
### CSS Positioning požadavky:
1. **`position: fixed`** - Navigace zůstává nahoře při scrollování
2. **`position: sticky`** - Aside zůstává viditelný při scrollování (od určitého bodu)
3. **`position: relative`** - Kontejner pro absolutně pozicované elementy
4. **`position: absolute`** - Badge "NOVÝ!" u jednoho projektu
### Design požadavky:
- Použijte jednotky: rem, em, vh (ne jen px!)
- Přidejte barvy a odstupy pro přehlednost
- Responzivní (aside zmizí na mobilu)
## 💡 Co se naučíte:
- Sémantické HTML5 elementy (nav, main, section, article, aside)
- CSS Positioning (fixed, sticky, relative, absolute)
- CSS jednotky (rem, em, vh, vw)
- Strukturu moderní webové stránky
## 🔗 Užitečné odkazy:
- HTML5 Semantic Elements: https://www.w3schools.com/html/html5_semantic_elements.asp
- CSS Position: https://css-tricks.com/almanac/properties/p/position/
## ⏱️ Odhadovaný čas: 60-90 minut

36
AI_extra_material/ai_02_semantic_portfolio/index.html

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 02 - Portfolio</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- TODO: Začněte zde -->
<!-- 1. Vytvořte <nav> s navigací -->
<!-- 2. Vytvořte <header> s úvodní sekcí -->
<!-- 3. Vytvořte <main> s hlavním obsahem -->
<!-- 3a. <section id="about"> - O mně -->
<!-- 3b. <section id="projects"> - Projekty (obsahuje 3x <article>) -->
<!-- 3c. <section id="contact"> - Kontakt s formulářem -->
<!-- 4. Vytvořte <aside> s rychlými informacemi (bude sticky) -->
<!-- 5. Vytvořte <footer> se zápatím -->
</body>
</html>

422
AI_extra_material/ai_02_semantic_portfolio/reseni.css

@ -0,0 +1,422 @@
/* AI 02 - Sémantické HTML5 & CSS Positioning - ŘEŠENÍ */
/* ============================================
ZÁKLADNÍ RESET A NASTAVENÍ
============================================ */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Root font-size pro REM jednotky */
html {
font-size: 16px; /* 1rem = 16px */
scroll-behavior: smooth; /* Plynulé scrollování k kotevním odkazům */
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
color: #333;
/* Padding-top kvůli fixní navigaci */
padding-top: 4rem;
}
/* ============================================
NAVIGACE - position: fixed
============================================ */
nav {
/* FIXED positioning - zůstává na stejném místě při scrollování */
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
background-color: #2c3e50;
padding: 1rem 0;
z-index: 1000; /* Vysoký z-index aby byl nav nad vším ostatním */
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.nav-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
color: white;
font-size: 1.5rem; /* 24px (16px * 1.5) */
margin: 0;
}
.nav-links {
display: flex;
list-style: none;
gap: 2rem; /* Mezery mezi položkami */
}
.nav-links a {
color: white;
text-decoration: none;
font-size: 1rem;
transition: color 0.3s ease;
}
.nav-links a:hover {
color: #3498db;
}
/* ============================================
HEADER - Úvodní sekce
============================================ */
header {
/* vh jednotka = viewport height (výška viewportu) */
height: 100vh; /* Celá výška obrazovky */
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
header h1 {
font-size: 3rem; /* 48px */
margin-bottom: 1rem;
animation: fadeInDown 1s ease;
}
.subtitle {
font-size: 1.5rem; /* 24px */
margin-bottom: 2rem;
opacity: 0.9;
}
.btn {
display: inline-block;
padding: 0.75rem 2rem;
background-color: white;
color: #667eea;
text-decoration: none;
border-radius: 30px;
font-weight: bold;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.btn:hover {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
/* ============================================
MAIN - Hlavní obsah
============================================ */
main {
max-width: 1200px;
margin: 0 auto;
padding: 0 2rem;
/* Margin-right pro aside (boční panel) */
margin-right: 320px;
}
/* ============================================
SECTION - Jednotlivé sekce
============================================ */
section {
padding: 4rem 0; /* rem jednotka (relativní k root font-size) */
border-bottom: 1px solid #eee;
}
section h2 {
font-size: 2.5rem; /* 40px */
margin-bottom: 2rem;
color: #2c3e50;
text-align: center;
}
/* O MNĚ sekce */
#about .about-content {
display: flex;
gap: 3rem;
align-items: center;
}
#about img {
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.about-text p {
margin-bottom: 1rem;
font-size: 1.1rem;
text-align: justify;
}
/* PROJEKTY sekce */
#projects .projects-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-top: 2rem;
}
/* ============================================
ARTICLE - Projekt karty
============================================ */
article.project-card {
background: white;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
/* RELATIVE positioning - vytváří kontext pro absolute positioning */
position: relative;
}
article.project-card:hover {
transform: translateY(-10px);
}
article.project-card img {
width: 100%;
height: auto;
display: block;
}
article.project-card h3 {
padding: 1rem;
font-size: 1.5rem;
color: #2c3e50;
}
article.project-card p {
padding: 0 1rem 1.5rem;
color: #666;
line-height: 1.6;
}
/* Badge "NOVÝ!" - position: absolute */
.badge {
/* ABSOLUTE positioning - pozicuje se relativně k prvnímu parent elementu s position: relative */
position: absolute;
top: 1rem;
right: 1rem;
background-color: #e74c3c;
color: white;
padding: 0.5rem 1rem;
border-radius: 20px;
font-weight: bold;
font-size: 0.875rem; /* 14px */
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
/* KONTAKT sekce */
#contact {
max-width: 600px;
margin: 0 auto;
}
.contact-form {
margin-top: 2rem;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: bold;
color: #2c3e50;
}
.form-group input,
.form-group textarea {
width: 100%;
padding: 0.75rem;
border: 2px solid #ddd;
border-radius: 5px;
font-size: 1rem;
font-family: inherit;
transition: border-color 0.3s ease;
}
.form-group input:focus,
.form-group textarea:focus {
outline: none;
border-color: #667eea;
}
/* ============================================
ASIDE - Boční panel, position: sticky
============================================ */
aside {
/* STICKY positioning - chová se jako relative, dokud nedosáhne určitého bodu, pak se chová jako fixed */
position: sticky;
top: 5rem; /* Odshora (pod navigací) */
/* Umístění vpravo */
position: fixed;
right: 2rem;
top: 6rem;
width: 250px;
background-color: #f8f9fa;
padding: 1.5rem;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
aside h3 {
color: #2c3e50;
margin-bottom: 1.5rem;
font-size: 1.25rem;
}
.info-item {
margin-bottom: 1rem;
padding-bottom: 1rem;
border-bottom: 1px solid #ddd;
}
.info-item:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
}
.info-item strong {
display: block;
color: #667eea;
margin-bottom: 0.25rem;
font-size: 0.875rem;
}
.info-item p {
color: #555;
margin: 0;
font-size: 0.875rem;
}
/* ============================================
FOOTER - Zápatí
============================================ */
footer {
background-color: #2c3e50;
color: white;
text-align: center;
padding: 2rem;
margin-top: 4rem;
margin-right: 320px; /* Kvůli aside */
}
footer p {
margin-bottom: 1rem;
}
.social-links {
display: flex;
justify-content: center;
gap: 2rem;
}
.social-links a {
color: white;
text-decoration: none;
transition: color 0.3s ease;
}
.social-links a:hover {
color: #3498db;
}
/* ============================================
ANIMACE
============================================ */
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* ============================================
MEDIA QUERIES - Responzivita
============================================ */
@media screen and (max-width: 768px) {
/* Schovat aside na menších obrazovkách */
aside {
display: none;
}
/* Odstranit margin-right z main a footer */
main,
footer {
margin-right: 0;
}
/* Úprava navigace */
.nav-container {
flex-direction: column;
gap: 1rem;
}
.nav-links {
gap: 1rem;
}
/* Zmenšit font sizes */
header h1 {
font-size: 2rem;
}
.subtitle {
font-size: 1.2rem;
}
section h2 {
font-size: 2rem;
}
/* O mně - stack na mobilu */
#about .about-content {
flex-direction: column;
}
/* Kontakt - celá šířka */
#contact {
max-width: 100%;
}
}
@media screen and (max-width: 480px) {
body {
padding-top: 6rem; /* Více místa pro higher nav */
}
main {
padding: 0 1rem;
}
section {
padding: 2rem 0;
}
.projects-grid {
grid-template-columns: 1fr;
}
}

119
AI_extra_material/ai_02_semantic_portfolio/reseni.html

@ -0,0 +1,119 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 02 - Portfolio - ŘEŠENÍ</title>
<link rel="stylesheet" href="reseni.css">
</head>
<body>
<!-- NAVIGACE - Sémantický element pro navigaci -->
<nav>
<div class="nav-container">
<h2 class="logo">MůjWeb</h2>
<ul class="nav-links">
<li><a href="#home">Domů</a></li>
<li><a href="#about">O mně</a></li>
<li><a href="#projects">Projekty</a></li>
<li><a href="#contact">Kontakt</a></li>
</ul>
</div>
</nav>
<!-- HEADER - Úvodní hlavička stránky -->
<header id="home">
<h1>Jan Novák</h1>
<p class="subtitle">Web Developer & Designer</p>
<a href="#about" class="btn">Více o mně</a>
</header>
<!-- MAIN - Hlavní obsah stránky -->
<main>
<!-- SECTION - Sémantický element pro sekci stránky -->
<section id="about">
<h2>O mně</h2>
<div class="about-content">
<img src="https://via.placeholder.com/300" alt="Profilový obrázek">
<div class="about-text">
<p>Jsem web developer s vášní pro vytváření moderních a responzivních webových stránek. Specializuji se na frontend technologie jako HTML, CSS, JavaScript a Bootstrap.</p>
<p>Ve volném čase se rád věnuji učení nových technologií a pracuji na open-source projektech. Mým cílem je vytvářet webové aplikace, které jsou nejen funkční, ale i esteticky příjemné.</p>
<p>Pokud hledáte někoho, kdo vašemu projektu dodá profesionální vzhled a špičkovou funkcionalitu, jste na správném místě!</p>
</div>
</div>
</section>
<!-- SECTION - Projekty -->
<section id="projects">
<h2>Moje Projekty</h2>
<div class="projects-grid">
<!-- ARTICLE - Sémantický element pro samostatný obsah -->
<article class="project-card">
<span class="badge">NOVÝ!</span>
<img src="https://via.placeholder.com/350x200" alt="Projekt 1">
<h3>E-shop s oblečením</h3>
<p>Moderní e-commerce stránka s košíkem, filtrováním produktů a responzivním designem. Použité technologie: HTML, CSS, JavaScript.</p>
</article>
<article class="project-card">
<img src="https://via.placeholder.com/350x200" alt="Projekt 2">
<h3>Portfolio fotografie</h3>
<p>Elegantní portfolio pro fotografa s galerií, lightboxem a plynulými animacemi. Optimalizováno pro mobily.</p>
</article>
<article class="project-card">
<img src="https://via.placeholder.com/350x200" alt="Projekt 3">
<h3>Firemní web</h3>
<p>Profesionální prezentace firmy s informacemi o službách, referencemi a kontaktním formulářem.</p>
</article>
</div>
</section>
<!-- SECTION - Kontakt -->
<section id="contact">
<h2>Kontaktujte mě</h2>
<form class="contact-form">
<div class="form-group">
<label for="name">Jméno:</label>
<input type="text" id="name" name="name" required>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="message">Zpráva:</label>
<textarea id="message" name="message" rows="5" required></textarea>
</div>
<button type="submit" class="btn">Odeslat zprávu</button>
</form>
</section>
</main>
<!-- ASIDE - Boční panel s rychlými informacemi -->
<aside>
<h3>Rychlé info</h3>
<div class="info-item">
<strong>Email:</strong>
<p>jan.novak@email.cz</p>
</div>
<div class="info-item">
<strong>Telefon:</strong>
<p>+420 123 456 789</p>
</div>
<div class="info-item">
<strong>Lokace:</strong>
<p>Praha, Česká republika</p>
</div>
</aside>
<!-- FOOTER - Zápatí stránky -->
<footer>
<p>&copy; 2025 Jan Novák. Všechna práva vyhrazena.</p>
<div class="social-links">
<a href="#">Facebook</a>
<a href="#">LinkedIn</a>
<a href="#">GitHub</a>
</div>
</footer>
</body>
</html>

54
AI_extra_material/ai_02_semantic_portfolio/style.css

@ -0,0 +1,54 @@
/* AI 02 - Sémantické HTML5 & CSS Positioning */
/* Základní reset a nastavení */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* TODO: Nastavte root font-size pro rem jednotky */
html {
/* 1rem = 16px (výchozí) */
}
body {
font-family: Arial, Helvetica, sans-serif;
line-height: 1.6;
color: #333;
}
/* TODO: NAVIGACE - position: fixed */
/* nav {} */
/* TODO: HEADER - úvodní sekce */
/* header {} */
/* TODO: MAIN - hlavní obsah */
/* main {} */
/* TODO: SECTION - jednotlivé sekce */
/* section {} */
/* TODO: ARTICLE - projekty */
/* article {} */
/* TODO: ASIDE - boční panel, position: sticky */
/* aside {} */
/* TODO: FOOTER - zápatí */
/* footer {} */
/* TODO: POSITIONING */
/* Vytvořte badge "NOVÝ!" s position: absolute */
/* TODO: MEDIA QUERIES */
/* Na mobilu (max-width: 768px) schovat aside */

301
AI_extra_material/ai_03_form_validation/README.md

@ -0,0 +1,301 @@
# AI 03 - Pokročilá Validace Formulářů s JavaScript
## 🎯 Cíl projektu
Naučit se **pokročilou práci s formuláři** a **JavaScript validací**. Bootstrap má vestavěné validační třídy, takže je důležité rozumět, jak validace funguje "pod kapotou".
## 📋 Co se naučíte
- **addEventListener** - moderní přístup místo inline `onclick`
- **Form validation** v JavaScriptu
- **RegEx** (regulární výrazy) pro validaci formátů
- **DOM manipulace** - `classList`, `innerHTML`, `textContent`
- **Event handling** - `input`, `submit` events
- **Real-time feedback** - validace při psaní
- **Visual feedback** - červená/zelená border, ikony, zprávy
## 📂 Soubory v projektu
- **ZADANI.md** - detailní zadání s požadavky na validaci
- **index.html** - startovací HTML (s TODO komentáři)
- **style.css** - CSS šablona
- **script.js** - JavaScript šablona (s TODO komentáři)
- **reseni.html** - kompletní řešení
- **reseni.css** - CSS s komentáři
- **reseni.js** - JavaScript s podrobnými komentáři
## 🚀 Jak pracovat s projektem
### Krok 1: Přečtěte si ZADANI.md
- Pochopte požadavky na validaci každého pole
- Projděte si příklady kódu
### Krok 2: Vytvořte registrační formulář
Formulář obsahuje:
1. **Jméno** - min 3 znaky, jen písmena
2. **Email** - validní formát
3. **Heslo** - min 8 znaků, velké písmeno, číslo, speciální znak
4. **Potvrzení hesla** - musí se shodovat
5. **Věk** - 18-120
6. **Souhlas s podmínkami** - checkbox
### Krok 3: Implementujte addEventListener
❌ **STARÝ způsob (inline):**
```html
<input type="text" onchange="validateName()">
```
✅ **NOVÝ způsob (addEventListener):**
```html
<input type="text" id="jmeno">
```
```javascript
document.getElementById("jmeno").addEventListener("input", validateName);
```
### Krok 4: Vytvořte validační funkce
```javascript
// Validace jména
function validateName() {
const nameInput = document.getElementById("jmeno");
const nameValue = nameInput.value;
const errorElement = document.getElementById("jmeno-error");
// Kontrola délky
if (nameValue.length < 3) {
showError(nameInput, errorElement, "Jméno musí mít alespoň 3 znaky");
return false;
}
// Kontrola pouze písmen (RegEx)
const nameRegex = /^[a-zA-ZáčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ\s]+$/;
if (!nameRegex.test(nameValue)) {
showError(nameInput, errorElement, "Jméno může obsahovat pouze písmena");
return false;
}
// Vše OK
showSuccess(nameInput, errorElement);
return true;
}
// Helper funkce
function showError(input, errorElement, message) {
input.classList.add("error");
input.classList.remove("success");
errorElement.textContent = message;
errorElement.style.display = "block";
}
function showSuccess(input, errorElement) {
input.classList.remove("error");
input.classList.add("success");
errorElement.style.display = "none";
}
```
## 💡 Klíčové koncepty
### addEventListener vs onclick:
```javascript
// ✅ MODERNÍ - addEventListener (doporučený)
const button = document.getElementById("myButton");
button.addEventListener("click", function() {
console.log("Kliknuto!");
});
// ❌ STARŠÍ - inline onclick
// <button onclick="handleClick()">Click</button>
```
**Výhody addEventListener:**
- Více listenerů na jeden element
- Oddělení HTML a JavaScriptu
- Možnost odstranit listener
- Lepší čitelnost
### RegEx příklady:
```javascript
// Email
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
emailRegex.test("user@email.com"); // true
// Heslo (min 8 znaků, velké, malé, číslo, spec. znak)
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
// Pouze písmena (včetně diakritiky)
const nameRegex = /^[a-zA-ZáčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ\s]+$/;
// Telefon (CZ formát)
const phoneRegex = /^(\+420)?[0-9]{9}$/;
```
### classList manipulace:
```javascript
// Přidání třídy
element.classList.add("error");
// Odebrání třídy
element.classList.remove("error");
// Toggle (přidá/odebere)
element.classList.toggle("active");
// Kontrola existence
if (element.classList.contains("error")) {
// ...
}
// Více tříd najednou
element.classList.add("error", "shake");
```
### Event types:
```javascript
// Při každé změně (real-time)
input.addEventListener("input", validateName);
// Po opuštění pole
input.addEventListener("blur", validateName);
// Při odeslání formuláře
form.addEventListener("submit", function(e) {
e.preventDefault(); // zabrání odeslání
// validace...
});
```
## 🎯 Úplný příklad - Email validace
```html
<!-- HTML -->
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" class="form-control">
<span class="error-message" id="email-error"></span>
</div>
```
```javascript
// JavaScript
document.getElementById("email").addEventListener("input", validateEmail);
function validateEmail() {
const emailInput = document.getElementById("email");
const emailValue = emailInput.value;
const errorElement = document.getElementById("email-error");
// Email regex
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(emailValue)) {
emailInput.classList.add("error");
emailInput.classList.remove("success");
errorElement.textContent = "Zadejte platný email";
errorElement.style.display = "block";
return false;
}
emailInput.classList.remove("error");
emailInput.classList.add("success");
errorElement.style.display = "none";
return true;
}
```
```css
/* CSS */
.form-control {
border: 2px solid #ccc;
transition: border-color 0.3s;
}
.form-control.error {
border-color: #dc3545; /* červená */
}
.form-control.success {
border-color: #28a745; /* zelená */
}
.error-message {
color: #dc3545;
font-size: 0.875rem;
display: none;
}
```
## ⚠️ Časté chyby
❌ **addEventListener s závorkami**
```javascript
// ŠPATNĚ
input.addEventListener("input", validateName()); // volá funkci hned
// SPRÁVNĚ
input.addEventListener("input", validateName); // předá referenci
```
❌ **Zapomenutý e.preventDefault()**
```javascript
form.addEventListener("submit", function(e) {
e.preventDefault(); // MUSÍ BÝT! Jinak se formulář odešle
// validace...
});
```
❌ **RegEx bez escape znaků**
```javascript
// ŠPATNĚ
const regex = /^user@email.com$/; // . = jakýkoliv znak
// SPRÁVNĚ
const regex = /^user@email\.com$/; // \. = literální tečka
```
## 🎓 Hodnocení (20 bodů)
- **addEventListener použití** (4b) - všechny eventy přes addEventListener
- **Validační funkce** (6b) - 6 funkčních validací
- **RegEx implementace** (3b) - správné regex pro email, heslo, jméno
- **Visual feedback** (4b) - červená/zelená border, chybové zprávy
- **Submit handling** (3b) - kontrola všech polí, preventDefault
## 🔗 Užitečné odkazy
- [Form Validation - W3Schools](https://www.w3schools.com/js/js_validation.asp)
- [RegEx Tutorial - RegExr](https://regexr.com/)
- [addEventListener - MDN](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
- [RegEx Tester - Regex101](https://regex101.com/)
## ⏱️ Odhadovaný čas
**90-120 minut**
## 💪 Bonus výzvy
1. **Password strength meter** - slabé/střední/silné heslo
2. **Show/hide password** - ikona oka pro zobrazení hesla
3. **Email suggestion** - když napíšu `@gmal.com` → návrh `@gmail.com`
4. **Character counter** - zobrazí 3/20 znaků
5. **Shake animation** - třese se při chybě
## 🎯 Po dokončení
Po dokončení tohoto projektu budete rozumět:
- Modernímu event handlingu (addEventListener)
- Form validation v JavaScriptu
- RegEx pro validaci formátů
- Visual feedback a UX best practices
Bootstrap form validation vám pak bude dávat smysl, protože budete vědět, co se děje "pod kapotou"!
➡️ **Další projekt:** AI 04 - Komplexní Bootstrap Prep Projekt

93
AI_extra_material/ai_03_form_validation/ZADANI.md

@ -0,0 +1,93 @@
# AI 03 - Pokročilá Validace Formulářů s JavaScript
## 🎯 Cíl projektu
Naučit se pokročilou práci s formuláři a JavaScript validací. Bootstrap má vestavěné validační třídy, takže je důležité rozumět, jak validace funguje.
## 📝 Zadání
Vytvořte registrační formulář s real-time validací pomocí JavaScriptu.
### HTML požadavky - Formulářové pole:
1. **Jméno** (text input)
- Min. 3 znaky, max. 20 znaků
- Pouze písmena
2. **Email** (email input)
- Musí obsahovat @ a .
- Validní formát emailu
3. **Heslo** (password input)
- Min. 8 znaků
- Alespoň 1 velké písmeno
- Alespoň 1 číslo
- Alespoň 1 speciální znak
4. **Potvrzení hesla** (password input)
- Musí se shodovat s heslem
5. **Věk** (number input)
- Min. 18, max. 120
6. **Souhlas s podmínkami** (checkbox)
- Musí být zaškrtnutý
7. **Tlačítko Registrovat** (button)
### JavaScript požadavky:
#### 1. Použijte `addEventListener` místo inline onclick!
```javascript
document.getElementById("jmeno").addEventListener("input", validateName);
```
#### 2. Real-time validace
- Validujte při každé změně (event: "input")
- Zobrazujte chybové zprávy pod každým polem
- Měňte border color (červená = chyba, zelená = OK)
#### 3. Validační funkce
Vytvořte separátní funkce pro validaci:
- `validateName()`
- `validateEmail()`
- `validatePassword()`
- `validatePasswordMatch()`
- `validateAge()`
- `validateCheckbox()`
#### 4. Submit validace
- Při kliknutí na "Registrovat" zkontrolujte všechna pole
- Pokud je něco špatně, zobrazte alert a zabraňte odeslání
- Pokud je vše OK, zobrazte success zprávu
#### 5. Visual feedback
- Červený border + chybová zpráva = chyba
- Zelený border = OK
- Ikona checkmark (✓) u správných polí
- Ikona X (✗) u chybných polí
### CSS požadavky:
- Hezký design formuláře
- Responzivní
- Animace při chybách (shake effect)
## 💡 Co se naučíte:
- addEventListener vs inline events
- Form validation v JavaScriptu
- RegEx (regulární výrazy) pro validaci
- DOM manipulace (classList, innerHTML)
- Event handling
- Podmínky a logické operátory
## 🔗 Užitečné odkazy:
- Form Validation: https://www.w3schools.com/js/js_validation.asp
- RegEx Tutorial: https://regexr.com/
- addEventListener: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
## ⏱️ Odhadovaný čas: 90-120 minut
## 💪 Bonus výzvy:
1. Password strength meter (slabé/střední/silné heslo)
2. Show/hide password tlačítko
3. Email suggestion (když napíšu @gmal.com → návrd @gmail.com)
4. Character counter pro jméno

50
AI_extra_material/ai_03_form_validation/index.html

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 03 - Validace Formulářů</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>Registrace</h1>
<form id="registrationForm">
<!-- TODO: Vytvořte formulářová pole podle zadání -->
<!-- Příklad struktury pro jedno pole: -->
<!--
<div class="form-group">
<label for="jmeno">Jméno:</label>
<input type="text" id="jmeno" name="jmeno">
<span class="error-message" id="jmenoError"></span>
</div>
-->
<!-- 1. Pole pro jméno -->
<!-- 2. Pole pro email -->
<!-- 3. Pole pro heslo -->
<!-- 4. Pole pro potvrzení hesla -->
<!-- 5. Pole pro věk -->
<!-- 6. Checkbox pro souhlas s podmínkami -->
<!-- 7. Tlačítko -->
</form>
</div>
<script src="script.js"></script>
</body>
</html>

256
AI_extra_material/ai_03_form_validation/reseni.css

@ -0,0 +1,256 @@
/* AI 03 - Validace Formulářů - ŘEŠENÍ */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
width: 100%;
max-width: 500px;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
font-size: 2rem;
}
/* ========================================
FORM STYLING
======================================== */
.form-group {
margin-bottom: 20px;
position: relative;
}
.form-group label {
display: block;
margin-bottom: 8px;
color: #333;
font-weight: 600;
font-size: 0.95rem;
}
.form-group input {
width: 100%;
padding: 12px 15px;
border: 2px solid #ddd;
border-radius: 5px;
font-size: 1rem;
transition: all 0.3s ease;
font-family: inherit;
}
.form-group input:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.form-group small {
display: block;
margin-top: 5px;
color: #999;
font-size: 0.85rem;
}
/* ========================================
VALIDATION STATES
======================================== */
/* SUCCESS - zelený border */
.form-group.success input {
border-color: #2ecc71;
}
/* Přidá checkmark ikonu */
.form-group.success input {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Cpath fill='%232ecc71' d='M7.629 14.566l-4.586-4.586-1.457 1.457 6.043 6.043 12.957-12.957-1.457-1.457z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
background-size: 20px;
padding-right: 40px;
}
/* ERROR - červený border */
.form-group.error input {
border-color: #e74c3c;
}
/* Přidá X ikonu */
.form-group.error input {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Cpath fill='%23e74c3c' d='M10 8.586l-7.071-7.071-1.414 1.414 7.071 7.071-7.071 7.071 1.414 1.414 7.071-7.071 7.071 7.071 1.414-1.414-7.071-7.071 7.071-7.071-1.414-1.414z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
background-size: 16px;
padding-right: 40px;
}
/* ========================================
ERROR MESSAGE
======================================== */
.error-message {
display: block;
color: #e74c3c;
font-size: 0.875rem;
margin-top: 5px;
min-height: 20px;
font-weight: 500;
}
/* ========================================
CHECKBOX GROUP
======================================== */
.checkbox-group {
margin-bottom: 25px;
}
.checkbox-group label {
display: flex;
align-items: center;
font-weight: normal;
cursor: pointer;
}
.checkbox-group input[type="checkbox"] {
width: auto;
margin-right: 10px;
cursor: pointer;
width: 18px;
height: 18px;
}
/* ========================================
SUBMIT BUTTON
======================================== */
.btn-submit {
width: 100%;
padding: 15px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 5px;
font-size: 1.1rem;
font-weight: bold;
cursor: pointer;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.btn-submit:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}
.btn-submit:active {
transform: translateY(0);
}
.btn-submit:disabled {
background: #ccc;
cursor: not-allowed;
transform: none;
}
/* ========================================
SUCCESS MESSAGE
======================================== */
.success-box {
text-align: center;
padding: 30px;
background-color: #d4edda;
border: 2px solid #28a745;
border-radius: 10px;
margin-top: 20px;
}
.success-box h2 {
color: #155724;
margin-bottom: 10px;
}
.success-box p {
color: #155724;
}
/* ========================================
ANIMATIONS
======================================== */
/* Shake animace pro chyby */
@keyframes shake {
0%, 100% {
transform: translateX(0);
}
10%, 30%, 50%, 70%, 90% {
transform: translateX(-10px);
}
20%, 40%, 60%, 80% {
transform: translateX(10px);
}
}
.form-group.error {
animation: shake 0.5s ease;
}
/* Fade in animace */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.success-box {
animation: fadeIn 0.5s ease;
}
/* ========================================
RESPONSIVE
======================================== */
@media screen and (max-width: 480px) {
.container {
padding: 25px;
}
h1 {
font-size: 1.5rem;
}
.form-group input {
padding: 10px 12px;
font-size: 0.95rem;
}
.btn-submit {
padding: 12px;
font-size: 1rem;
}
}

76
AI_extra_material/ai_03_form_validation/reseni.html

@ -0,0 +1,76 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 03 - Validace Formulářů - ŘEŠENÍ</title>
<link rel="stylesheet" href="reseni.css">
</head>
<body>
<div class="container">
<h1>Registrace</h1>
<form id="registrationForm">
<!-- Jméno -->
<div class="form-group">
<label for="jmeno">Jméno:</label>
<input type="text" id="jmeno" name="jmeno" placeholder="Jan Novák">
<span class="error-message" id="jmenoError"></span>
<small>Min. 3 znaky, max. 20 znaků, pouze písmena</small>
</div>
<!-- Email -->
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" name="email" placeholder="jan@email.cz">
<span class="error-message" id="emailError"></span>
<small>Zadejte platný email</small>
</div>
<!-- Heslo -->
<div class="form-group">
<label for="heslo">Heslo:</label>
<input type="password" id="heslo" name="heslo" placeholder="••••••••">
<span class="error-message" id="hesloError"></span>
<small>Min. 8 znaků, 1 velké písmeno, 1 číslo, 1 speciální znak</small>
</div>
<!-- Potvrzení hesla -->
<div class="form-group">
<label for="hesloPotvrzeni">Potvrzení hesla:</label>
<input type="password" id="hesloPotvrzeni" name="hesloPotvrzeni" placeholder="••••••••">
<span class="error-message" id="hesloPotvrzeniError"></span>
<small>Hesla se musí shodovat</small>
</div>
<!-- Věk -->
<div class="form-group">
<label for="vek">Věk:</label>
<input type="number" id="vek" name="vek" placeholder="18">
<span class="error-message" id="vekError"></span>
<small>Min. 18 let</small>
</div>
<!-- Checkbox -->
<div class="form-group checkbox-group">
<label>
<input type="checkbox" id="souhlas" name="souhlas">
Souhlasím s podmínkami používání
</label>
<span class="error-message" id="souhlasError"></span>
</div>
<!-- Submit button -->
<button type="submit" class="btn-submit">Registrovat</button>
</form>
<!-- Success message (skrytá) -->
<div id="successMessage" class="success-box" style="display: none;">
<h2>✓ Registrace úspěšná!</h2>
<p>Váš účet byl úspěšně vytvořen.</p>
</div>
</div>
<script src="reseni.js"></script>
</body>
</html>

376
AI_extra_material/ai_03_form_validation/reseni.js

@ -0,0 +1,376 @@
// AI 03 - Validace Formulářů - ŘEŠENÍ
console.log("Script načten");
// ========================================
// ZÍSKÁNÍ REFERENCÍ NA ELEMENTY
// ========================================
const jmenoInput = document.getElementById("jmeno");
const emailInput = document.getElementById("email");
const hesloInput = document.getElementById("heslo");
const hesloPotvrzeniInput = document.getElementById("hesloPotvrzeni");
const vekInput = document.getElementById("vek");
const souhlasInput = document.getElementById("souhlas");
const form = document.getElementById("registrationForm");
const successMessage = document.getElementById("successMessage");
// ========================================
// EVENT LISTENERS - REAL-TIME VALIDACE
// ========================================
// Důležité: Používáme addEventListener místo inline onclick!
// Výhody:
// 1. Oddělení HTML a JavaScriptu
// 2. Můžeme přidat více listenerů na jeden element
// 3. Lepší kontrola nad event objektem
jmenoInput.addEventListener("input", validateName);
emailInput.addEventListener("input", validateEmail);
hesloInput.addEventListener("input", validatePassword);
hesloPotvrzeniInput.addEventListener("input", validatePasswordMatch);
vekInput.addEventListener("input", validateAge);
souhlasInput.addEventListener("change", validateCheckbox);
// Event listener pro submit formuláře
form.addEventListener("submit", handleSubmit);
// ========================================
// VALIDAČNÍ FUNKCE
// ========================================
/**
* Validace jména
* Požadavky:
* - Min. 3 znaky
* - Max. 20 znaků
* - Pouze písmena (včetně diakritiky)
*/
function validateName() {
const jmeno = jmenoInput.value.trim();
// Kontrola prázdného pole
if (jmeno === "") {
showError(jmenoInput, "Jméno je povinné");
return false;
}
// Kontrola délky
if (jmeno.length < 3) {
showError(jmenoInput, "Jméno musí mít alespoň 3 znaky");
return false;
}
if (jmeno.length > 20) {
showError(jmenoInput, "Jméno může mít maximálně 20 znaků");
return false;
}
// RegEx pro kontrolu, že obsahuje pouze písmena (včetně české diakritiky)
// ^ = začátek stringu
// [a-zA-Z...] = povolené znaky
// \s = mezera (povolíme mezery mezi jménem a příjmením)
// + = jeden nebo více
// $ = konec stringu
const nameRegex = /^[a-zA-ZáčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ\s]+$/;
if (!nameRegex.test(jmeno)) {
showError(jmenoInput, "Jméno může obsahovat pouze písmena");
return false;
}
// Vše OK!
showSuccess(jmenoInput);
return true;
}
/**
* Validace emailu
* Požadavek: Validní formát emailu (obsahuje @ a .)
*/
function validateEmail() {
const email = emailInput.value.trim();
if (email === "") {
showError(emailInput, "Email je povinný");
return false;
}
// RegEx pro email validaci
// [^\s@]+ = jeden nebo více znaků, které nejsou mezera nebo @
// @ = musí obsahovat @
// [^\s@]+ = doména
// \. = musí obsahovat tečku
// [^\s@]+ = koncovka (.cz, .com, atd.)
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
showError(emailInput, "Zadejte platný email");
return false;
}
showSuccess(emailInput);
return true;
}
/**
* Validace hesla
* Požadavky:
* - Min. 8 znaků
* - Alespoň 1 velké písmeno
* - Alespoň 1 číslo
* - Alespoň 1 speciální znak
*/
function validatePassword() {
const heslo = hesloInput.value;
if (heslo === "") {
showError(hesloInput, "Heslo je povinné");
return false;
}
// Kontrola délky
if (heslo.length < 8) {
showError(hesloInput, "Heslo musí mít alespoň 8 znaků");
return false;
}
// Kontrola velkého písmena
// [A-Z] = obsahuje alespoň jedno velké písmeno
if (!/[A-Z]/.test(heslo)) {
showError(hesloInput, "Heslo musí obsahovat alespoň jedno velké písmeno");
return false;
}
// Kontrola čísla
// [0-9] = obsahuje alespoň jedno číslo
if (!/[0-9]/.test(heslo)) {
showError(hesloInput, "Heslo musí obsahovat alespoň jedno číslo");
return false;
}
// Kontrola speciálního znaku
// [!@#$%^&*] = obsahuje alespoň jeden speciální znak
if (!/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(heslo)) {
showError(hesloInput, "Heslo musí obsahovat alespoň jeden speciální znak");
return false;
}
showSuccess(hesloInput);
// Pokud je heslo validní, zkontroluj i potvrzení hesla
if (hesloPotvrzeniInput.value !== "") {
validatePasswordMatch();
}
return true;
}
/**
* Validace shody hesel
*/
function validatePasswordMatch() {
const heslo = hesloInput.value;
const hesloPotvrzeni = hesloPotvrzeniInput.value;
if (hesloPotvrzeni === "") {
showError(hesloPotvrzeniInput, "Potvrzení hesla je povinné");
return false;
}
// Porovnání hesel
if (heslo !== hesloPotvrzeni) {
showError(hesloPotvrzeniInput, "Hesla se neshodují");
return false;
}
showSuccess(hesloPotvrzeniInput);
return true;
}
/**
* Validace věku
* Požadavek: Min. 18 let, max. 120 let
*/
function validateAge() {
const vek = parseInt(vekInput.value);
if (isNaN(vek) || vekInput.value === "") {
showError(vekInput, "Věk je povinný");
return false;
}
if (vek < 18) {
showError(vekInput, "Musíte být starší 18 let");
return false;
}
if (vek > 120) {
showError(vekInput, "Zadejte reálný věk");
return false;
}
showSuccess(vekInput);
return true;
}
/**
* Validace checkboxu
* Požadavek: Musí být zaškrtnutý
*/
function validateCheckbox() {
// .checked vrací true/false podle toho, jestli je checkbox zaškrtnutý
if (!souhlasInput.checked) {
showError(souhlasInput, "Musíte souhlasit s podmínkami");
return false;
}
showSuccess(souhlasInput);
return true;
}
// ========================================
// HELPER FUNKCE
// ========================================
/**
* Zobrazí chybovou zprávu a nastaví error stav
* @param {HTMLElement} inputElement - Input element
* @param {string} message - Chybová zpráva
*/
function showError(inputElement, message) {
// Najdi parent element (.form-group)
// .parentElement vrací rodičovský element
const formGroup = inputElement.parentElement;
// Přidej třídu "error" pro styling
formGroup.classList.add("error");
// Odeber třídu "success" (pokud tam byla)
formGroup.classList.remove("success");
// Najdi element pro chybovou zprávu
// Předpokládáme, že má id ve formátu: inputId + "Error"
const errorElement = formGroup.querySelector(".error-message");
// Nastav text chybové zprávy
if (errorElement) {
errorElement.textContent = message;
}
}
/**
* Zobrazí success stav (zelený border, checkmark)
* @param {HTMLElement} inputElement - Input element
*/
function showSuccess(inputElement) {
const formGroup = inputElement.parentElement;
// Přidej třídu "success"
formGroup.classList.add("success");
// Odeber třídu "error"
formGroup.classList.remove("error");
// Vyčisti chybovou zprávu
const errorElement = formGroup.querySelector(".error-message");
if (errorElement) {
errorElement.textContent = "";
}
}
// ========================================
// SUBMIT HANDLER
// ========================================
/**
* Handler pro submit formuláře
* @param {Event} e - Event objekt
*/
function handleSubmit(e) {
// Zabraň výchozímu chování (odeslání formuláře a reload stránky)
e.preventDefault();
console.log("Formulář odeslán");
// Zavolej všechny validační funkce
const isNameValid = validateName();
const isEmailValid = validateEmail();
const isPasswordValid = validatePassword();
const isPasswordMatchValid = validatePasswordMatch();
const isAgeValid = validateAge();
const isCheckboxValid = validateCheckbox();
// Zkontroluj, jestli jsou všechna pole validní
// Logický AND (&&) - vrací true pouze pokud jsou všechny hodnoty true
const isFormValid =
isNameValid &&
isEmailValid &&
isPasswordValid &&
isPasswordMatchValid &&
isAgeValid &&
isCheckboxValid;
if (isFormValid) {
// Vše OK - zobraz success zprávu
console.log("✓ Formulář je validní!");
// Schovat formulář
form.style.display = "none";
// Zobrazit success zprávu
successMessage.style.display = "block";
// V reálné aplikaci bychom zde odeslali data na server:
// fetch("/api/register", {
// method: "POST",
// body: JSON.stringify({
// jmeno: jmenoInput.value,
// email: emailInput.value,
// ...
// })
// });
} else {
// Něco je špatně - zobraz alert
console.log("✗ Formulář obsahuje chyby!");
alert("Prosím opravte chyby ve formuláři");
}
}
// ========================================
// BONUS FUNKCE
// ========================================
/**
* BONUS: Password strength meter
* Můžete přidat indikátor síly hesla
*/
function checkPasswordStrength(password) {
let strength = 0;
if (password.length >= 8) strength++;
if (password.length >= 12) strength++;
if (/[a-z]/.test(password)) strength++;
if (/[A-Z]/.test(password)) strength++;
if (/[0-9]/.test(password)) strength++;
if (/[^a-zA-Z0-9]/.test(password)) strength++;
if (strength <= 2) return "Slabé";
if (strength <= 4) return "Střední";
return "Silné";
}
// ========================================
// DEBUG INFO
// ========================================
console.log("Validační skrip připraven");
console.log("Event listenery přidány na:", {
jmeno: jmenoInput,
email: emailInput,
heslo: hesloInput,
hesloPotvrzeni: hesloPotvrzeniInput,
vek: vekInput,
souhlas: souhlasInput
});

96
AI_extra_material/ai_03_form_validation/script.js

@ -0,0 +1,96 @@
// AI 03 - Validace Formulářů - JavaScript
console.log("Script načten");
// TODO: Získejte reference na elementy
// const jmenoInput = document.getElementById("jmeno");
// const emailInput = document.getElementById("email");
// ... atd
// TODO: Přidejte event listenery pro real-time validaci
// jmenoInput.addEventListener("input", validateName);
// emailInput.addEventListener("input", validateEmail);
// ... atd
// TODO: Event listener pro submit formuláře
// document.getElementById("registrationForm").addEventListener("submit", handleSubmit);
// ========================================
// VALIDAČNÍ FUNKCE
// ========================================
// TODO: Funkce pro validaci jména
function validateName() {
// 1. Získej hodnotu z inputu
// 2. Zkontroluj délku (min 3, max 20)
// 3. Zkontroluj, že obsahuje jen písmena (použij RegEx: /^[a-zA-ZáčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ\s]+$/)
// 4. Zobraz chybu nebo success
}
// TODO: Funkce pro validaci emailu
function validateEmail() {
// 1. Získej hodnotu
// 2. Zkontroluj formát emailu (RegEx: /^[^\s@]+@[^\s@]+\.[^\s@]+$/)
// 3. Zobraz výsledek
}
// TODO: Funkce pro validaci hesla
function validatePassword() {
// Musí obsahovat:
// - Min. 8 znaků
// - Alespoň 1 velké písmeno (RegEx: /[A-Z]/)
// - Alespoň 1 číslo (RegEx: /[0-9]/)
// - Alespoň 1 speciální znak (RegEx: /[!@#$%^&*]/)
}
// TODO: Funkce pro kontrolu shody hesel
function validatePasswordMatch() {
// Porovnej hodnoty hesla a potvrzení hesla
}
// TODO: Funkce pro validaci věku
function validateAge() {
// Zkontroluj, že věk je číslo mezi 18 a 120
}
// TODO: Funkce pro validaci checkboxu
function validateCheckbox() {
// Zkontroluj, že checkbox je zaškrtnutý (.checked)
}
// ========================================
// HELPER FUNKCE
// ========================================
// TODO: Funkce pro zobrazení chyby
function showError(inputElement, message) {
// 1. Najdi parent element (.form-group)
// 2. Přidej třídu "error"
// 3. Odeber třídu "success"
// 4. Najdi .error-message a nastav text
// 5. Přidej shake animaci
}
// TODO: Funkce pro zobrazení success
function showSuccess(inputElement) {
// 1. Najdi parent element
// 2. Přidej třídu "success"
// 3. Odeber třídu "error"
// 4. Vyčisti error message
}
// ========================================
// SUBMIT HANDLER
// ========================================
function handleSubmit(e) {
e.preventDefault(); // Zabraň odeslání formuláře
// TODO: Zavolej všechny validační funkce
// TODO: Zkontroluj, jestli jsou všechna pole validní
// TODO: Pokud ano, zobraz success zprávu
// TODO: Pokud ne, zobraz alert s chybou
}

59
AI_extra_material/ai_03_form_validation/style.css

@ -0,0 +1,59 @@
/* AI 03 - Validace Formulářů */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, Helvetica, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
width: 100%;
max-width: 500px;
}
h1 {
text-align: center;
color: #333;
margin-bottom: 30px;
}
/* TODO: Nastylujte .form-group */
/* TODO: Nastylujte label */
/* TODO: Nastylujte input */
/* TODO: Přidejte třídy pro validaci */
/* .form-group.success input - zelený border */
/* .form-group.error input - červený border */
/* TODO: Nastylujte .error-message */
/* TODO: Nastylujte button */
/* TODO: Přidejte shake animaci pro chyby */
@keyframes shake {
/* Vytvořte shake efekt pomocí translateX */
}

377
AI_extra_material/ai_04_prep_bootstrap/README.md

@ -0,0 +1,377 @@
# AI 04 - Komplexní Bootstrap Prep Projekt
## 🎯 Cíl projektu
**Finální komplexní projekt** kombinující **VŠECHNY naučené koncepty**. Po dokončení tohoto projektu budete plně připraveni na Bootstrap a budete rozumět, proč a jak framework funguje!
## 📋 Co tento projekt procvičuje
### HTML:
✅ Sémantické elementy (nav, main, section, article, aside, footer)
✅ Formuláře
✅ Strukturu moderní webové stránky
### CSS:
**Grid & Flexbox** - komplexní layouty
**Positioning** - všechny typy (fixed, sticky, relative, absolute)
**Media queries** - plná responzivita
**CSS proměnné** - custom properties
**Moderní jednotky** - rem, em, vh, vw
✅ **Gradienty, shadows, transitions**
**Animations** - fadeIn, slideIn
**Pokročilé selektory** - nth-child, ::before, ::after
### JavaScript:
✅ **addEventListener**
✅ **DOM manipulace**
✅ **Form validation**
✅ **Event handling**
✅ **Scroll efekty**
✅ **Modals, accordions, toggles**
## 📂 Soubory v projektu
- **ZADANI.md** - kompletní zadání projektu
- **index.html** - startovací HTML (s TODO komentáři)
- **css/style.css** - hlavní CSS (s TODO komentáři)
- **css/animations.css** - CSS animace
- **js/main.js** - hlavní JavaScript
- **js/validation.js** - form validace
- **js/scroll.js** - scroll efekty
- **reseni/** - kompletní řešení se všemi soubory
## 🚀 Co budete vytvářet
**Responzivní Landing Page** pro fiktivní produkt (fitness app, e-learning, SaaS, atd.)
### Struktura stránky:
```
┌─────────────────────────────────────┐
│ FIXNÍ NAVIGACE (position: fixed) │
├─────────────────────────────────────┤
│ │
│ HERO SEKCE (header) │
│ Call-to-Action tlačítko │
│ │
├──────────────┬──────────────────────┤
│ STICKY │ │
│ ASIDE │ FEATURES (grid) │
│ (boční) │ │
│ │ PRICING CARDS │
│ │ (grid) │
│ │ │
│ │ TESTIMONIALS │
│ │ (flex) │
│ │ │
│ │ CONTACT FORM │
│ │ (validation) │
├──────────────┴──────────────────────┤
│ FOOTER │
└─────────────────────────────────────┘
```
## 💡 Klíčové techniky
### 1. CSS Grid Layout
**Features sekce:**
```css
.features {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 sloupce */
gap: 2rem;
}
@media (max-width: 768px) {
.features {
grid-template-columns: repeat(2, 1fr); /* 2 na tabletu */
}
}
@media (max-width: 480px) {
.features {
grid-template-columns: 1fr; /* 1 na mobilu */
}
}
```
### 2. CSS Proměnné (Custom Properties)
```css
:root {
--primary-color: #667eea;
--secondary-color: #764ba2;
--text-color: #333;
--bg-color: #f8f9fa;
--spacing-unit: 1rem;
--border-radius: 8px;
}
.button {
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
padding: calc(var(--spacing-unit) * 0.75) calc(var(--spacing-unit) * 1.5);
border-radius: var(--border-radius);
}
```
### 3. Pricing Toggle (JavaScript)
```javascript
const toggle = document.getElementById("pricing-toggle");
const monthlyPrices = document.querySelectorAll(".monthly-price");
const yearlyPrices = document.querySelectorAll(".yearly-price");
toggle.addEventListener("change", function() {
if (this.checked) {
// Zobraz roční ceny
monthlyPrices.forEach(el => el.style.display = "none");
yearlyPrices.forEach(el => el.style.display = "block");
} else {
// Zobraz měsíční ceny
monthlyPrices.forEach(el => el.style.display = "block");
yearlyPrices.forEach(el => el.style.display = "none");
}
});
```
### 4. Smooth Scroll k sekcím
```javascript
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener("click", function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute("href"));
target.scrollIntoView({
behavior: "smooth",
block: "start"
});
});
});
```
### 5. Scroll to Top tlačítko
```javascript
const scrollTopBtn = document.getElementById("scroll-top");
window.addEventListener("scroll", function() {
if (window.pageYOffset > 300) {
scrollTopBtn.classList.add("show");
} else {
scrollTopBtn.classList.remove("show");
}
});
scrollTopBtn.addEventListener("click", function() {
window.scrollTo({
top: 0,
behavior: "smooth"
});
});
```
### 6. Modal okno
```javascript
const modal = document.getElementById("myModal");
const openBtn = document.getElementById("openModal");
const closeBtn = document.querySelector(".close");
openBtn.addEventListener("click", function() {
modal.style.display = "block";
document.body.style.overflow = "hidden"; // zakáže scrollování
});
closeBtn.addEventListener("click", function() {
modal.style.display = "none";
document.body.style.overflow = "auto";
});
// Zavření kliknutím mimo modal
window.addEventListener("click", function(e) {
if (e.target === modal) {
modal.style.display = "none";
document.body.style.overflow = "auto";
}
});
```
### 7. FAQ Accordion
```javascript
const accordionHeaders = document.querySelectorAll(".accordion-header");
accordionHeaders.forEach(header => {
header.addEventListener("click", function() {
const content = this.nextElementSibling;
const isActive = this.classList.contains("active");
// Zavři všechny ostatní
accordionHeaders.forEach(h => {
h.classList.remove("active");
h.nextElementSibling.style.maxHeight = null;
});
// Toggle aktuální
if (!isActive) {
this.classList.add("active");
content.style.maxHeight = content.scrollHeight + "px";
}
});
});
```
### 8. Změna barvy navigace při scrollování
```javascript
const navbar = document.querySelector("nav");
window.addEventListener("scroll", function() {
if (window.pageYOffset > 100) {
navbar.classList.add("scrolled");
} else {
navbar.classList.remove("scrolled");
}
});
```
```css
nav {
background-color: transparent;
transition: background-color 0.3s ease;
}
nav.scrolled {
background-color: rgba(255, 255, 255, 0.95);
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
```
## 🎨 CSS Animations
```css
/* Fade In */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.fade-in {
animation: fadeIn 0.6s ease-out;
}
/* Slide In */
@keyframes slideIn {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
```
## ⚠️ Časté chyby a řešení
❌ **Fixed navigace překrývá obsah**
```css
body {
padding-top: 80px; /* výška navigace */
}
```
❌ **Smooth scroll nefunguje**
```css
html {
scroll-behavior: smooth; /* CSS alternativa */
}
```
❌ **Modal scrolluje pozadí**
```javascript
// Při otevření modalu
document.body.style.overflow = "hidden";
// Při zavření
document.body.style.overflow = "auto";
```
## 🎓 Hodnocení (30 bodů)
- **HTML struktura** (5b) - sémantické elementy, správná struktura
- **CSS Grid & Flexbox** (6b) - grid pro features/pricing, flex pro navigaci
- **Positioning** (4b) - fixed nav, sticky aside, absolute badge
- **JavaScript interaktivita** (6b) - validace, scroll, modal, accordion
- **Responzivita** (4b) - funguje na mobilu, tabletu, desktopu
- **Design & UX** (3b) - hezký design, dobré barvy, transitions
- **Clean code** (2b) - čitelný, okomentovaný kód
## 🔗 Design inspirace
- [Awwwards](https://www.awwwards.com/)
- [Dribbble](https://dribbble.com/)
- [Land-book](https://land-book.com/)
## ⏱️ Odhadovaný čas
**4-6 hodin** (pracujte postupně, ne vše najednou!)
## 💪 Bonus úkoly (nepovinné)
1. **Counter animace** - číselné statistiky se animují od 0
2. **Lazy loading obrázků** - obrázky se načtou až při scrollování
3. **Dark mode toggle** - přepínač světlý/tmavý režim
4. **Carousel/Slider** - pro testimonials (bez knihoven!)
5. **Newsletter signup** - s fake AJAX requestem
6. **AOS (Animate On Scroll)** - prvky plynule přijíždějí při scrollování
## 🎯 Po dokončení projektu
### Co budete rozumět při učení Bootstrapu:
**Grid systém** - víte, jak funguje pod kapotou
**Utility třídy** - `.m-2`, `.p-3` → víte, co dělají
**Komponenty** - modals, accordions → umíte je vytvořit sami
**JavaScript plugins** - rozumíte, jak fungují
**Responzivita** - mobile-first přístup dává smysl
### Bootstrap vám ušetří čas:
```html
<!-- VÁŠE ŘEŠENÍ (40 řádků CSS) -->
<div class="pricing-card">
<h3>Basic</h3>
<p class="price">$9/mo</p>
<button class="btn">Subscribe</button>
</div>
<!-- BOOTSTRAP (využívá hotové třídy) -->
<div class="card text-center">
<div class="card-body">
<h3 class="card-title">Basic</h3>
<p class="display-4">$9/mo</p>
<button class="btn btn-primary">Subscribe</button>
</div>
</div>
```
**Ale díky tomuto projektu víte, co se děje pod kapotou!** 🎉
## 🏆 Gratulace!
Po dokončení všech AI projektů (01-04) jste připraveni na Bootstrap!
Jste schopni:
- ✅ Vytvořit kompletní responzivní web bez frameworku
- ✅ Rozumět, jak frameworky fungují interně
- ✅ Přizpůsobit Bootstrap vlastním potřebám
- ✅ Debugovat problémy v Bootstrapu
➡️ **Další krok:** Lekce 13 - Úvod do Bootstrapu

173
AI_extra_material/ai_04_prep_bootstrap/RESENI_PRIKLAD.md

@ -0,0 +1,173 @@
# Příklad řešení - AI 04
Toto je **zjednodušený příklad** řešení. Vaše implementace by měla být completnější!
## Struktura HTML (příklad hero sekce)
```html
<header id="hero">
<div class="hero-content">
<h1 class="hero-title">FitPro</h1>
<p class="hero-subtitle">Vaše cesta k lepší kondici začíná zde</p>
<a href="#contact" class="btn btn-primary">Začít zdarma</a>
</div>
</header>
```
## CSS Grid příklad (features)
```css
.features-grid {
display: grid;
grid-template-columns: 1fr; /* Mobil - 1 sloupec */
gap: 2rem;
padding: 4rem 2rem;
}
@media (min-width: 768px) {
.features-grid {
grid-template-columns: repeat(2, 1fr); /* Tablet - 2 sloupce */
}
}
@media (min-width: 1024px) {
.features-grid {
grid-template-columns: repeat(3, 1fr); /* Desktop - 3 sloupce */
}
}
```
## JavaScript smooth scroll příklad
```javascript
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
});
});
```
## Positioning příklad (badge)
```css
.pricing-card {
position: relative; /* Vytvoří kontext pro absolute */
}
.badge {
position: absolute;
top: -10px;
right: -10px;
background: var(--danger-color);
color: white;
padding: 0.5rem 1rem;
border-radius: 20px;
}
```
## CSS Proměnné použití
```css
.btn-primary {
background: linear-gradient(
135deg,
var(--primary-color),
var(--secondary-color)
);
color: var(--white);
padding: var(--spacing-sm) var(--spacing-md);
}
```
## Tips & Tricks
### 1. Responzivní typografie s clamp()
```css
h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
```
### 2. Aspect ratio pro obrázky
```css
.image-container {
aspect-ratio: 16/9;
overflow: hidden;
}
```
### 3. Flexbox centering
```css
.centered {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
```
### 4. Grid auto-fit
```css
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
```
## Checklist před odevzdáním
- [ ] Všechny sémantické HTML5 elementy použity
- [ ] CSS Grid pro alespoň 2 sekce
- [ ] Flexbox pro alespoň 2 sekce
- [ ] Všechny 4 typy positioning použity
- [ ] Minimálně 3 media queries
- [ ] Formulář s funkční validací
- [ ] Smooth scroll implementován
- [ ] Scroll to top button funguje
- [ ] Použity CSS proměnné
- [ ] Použity rem/em jednotky (ne jen px)
- [ ] Hover efekty na interaktivních prvcích
- [ ] Animace při načtení stránky
- [ ] Responzivní na všech zařízeních
- [ ] Kód je komentovaný
- [ ] Žádné console errory
## Hodnocení
### Základní požadavky (70 bodů)
- HTML struktura (10 bodů)
- CSS Grid (10 bodů)
- Flexbox (10 bodů)
- Positioning (10 bodů)
- Media queries (10 bodů)
- JavaScript validace (10 bodů)
- Scroll efekty (10 bodů)
### Pokročilé funkce (20 bodů)
- CSS proměnné (5 bodů)
- Animace (5 bodů)
- Pokročilé selektory (5 bodů)
- Clean code (5 bodů)
### Bonus (10 bodů)
- Extra funkce (modal, accordion, atd.)
- Výjimečný design
- Originální nápady
**Celkem: 100 bodů (+10 bonus)**
## Užitečné zdroje
- MDN Web Docs: https://developer.mozilla.org/
- CSS Tricks: https://css-tricks.com/
- Can I Use: https://caniuse.com/
- Coolors (palety barev): https://coolors.co/
- Google Fonts: https://fonts.google.com/
Hodně štěstí! 🚀

166
AI_extra_material/ai_04_prep_bootstrap/ZADANI.md

@ -0,0 +1,166 @@
# AI 04 - Komplexní Bootstrap Prep Projekt
## 🎯 Cíl projektu
Komplexní projekt kombinující VŠECHNY naučené koncepty. Po dokončení tohoto projektu budete připraveni na Bootstrap!
## 📝 Zadání
Vytvořte **Responzivní Landing Page pro fiktivní produkt** (např. fitness aplikace, e-learning platforma, nebo jakýkoliv produkt dle vlastního výběru).
### Požadavky na projekt:
## 1️⃣ HTML - Sémantická struktura
Použijte tyto sémantické elementy:
- `<nav>` - Fixní navigace s logem a menu
- `<header>` - Hero sekce s call-to-action
- `<main>` obsahující:
- `<section id="features">` - 3-6 features (ikony + text)
- `<section id="pricing">` - 3 cenové karty
- `<section id="testimonials">` - 3 recenze zákazníků
- `<section id="contact">` - Kontaktní formulář
- `<aside>` - Boční panel s quick links (sticky)
- `<footer>` - Zápatí s odkazy
## 2️⃣ CSS - Layout & Design
### Grid Layout:
- Features sekce: CSS Grid, 3 sloupce (desktop), 2 (tablet), 1 (mobil)
- Pricing karty: CSS Grid, 3 sloupce s gap 2rem
### Flexbox:
- Navigace: flex s space-between
- Footer: flex s justify-content: space-around
- Testimonials: flex s flex-wrap
### Positioning:
- `position: fixed` - Navigace
- `position: sticky` - Aside
- `position: absolute` - Badge "NEJLEPŠÍ VOLBA!" na jedné cenové kartě
- `position: relative` - Kontejner pro badge
### Responzivita:
- Mobile first approach!
- Breakpoints: 480px, 768px, 1024px
- Media queries pro všechny sekce
### Design:
- Použijte CSS proměnné (custom properties):
```css
:root {
--primary-color: #667eea;
--secondary-color: #764ba2;
--text-color: #333;
--bg-color: #f8f9fa;
}
```
- Jednotky: rem, em, vh, vw (ne jen px!)
- Gradienty na pozadí
- Box shadows pro depth
- Hover efekty s transitions
- Animations (fadeIn, slideIn)
## 3️⃣ JavaScript - Interaktivita
### Formulář s validací:
- Jméno (min 3 znaky)
- Email (validní formát)
- Zpráva (min 10 znaků)
- Real-time validace pomocí `addEventListener`
- Visual feedback (červená/zelená)
### Scroll efekty:
- Smooth scroll k sekcím při kliknutí na menu
- "Scroll to top" tlačítko (zobrazí se po scrollování)
- Změna barvy navigace při scrollování
### Interaktivní features:
- Pricing toggle: měsíční/roční ceny (switch button)
- FAQ accordion (kliknutí → otevře/zavře odpověď)
- Modal okno pro "Více informací" tlačítko
### Bonus:
- Counter animace (číselné statistiky se animují od 0)
- Lazy loading obrázků
- Dark mode toggle
## 4️⃣ Pokročilé CSS selektory
Použijte minimálně:
- `:nth-child()` - styling každé druhé karty
- `:hover`, `:focus`, `:active`
- `:first-child`, `:last-child`
- `::before`, `::after` - pro dekorativní elementy
- Attribute selectors - `[href^="http"]` pro externí odkazy
## 📐 Struktura projektu
```
ai_04_prep_bootstrap/
├── index.html
├── css/
│ ├── style.css
│ └── animations.css
├── js/
│ ├── main.js
│ ├── validation.js
│ └── scroll.js
└── images/
└── (vaše obrázky)
```
## 💡 Co tento projekt procvičuje:
### HTML:
✓ Sémantické elementy
✓ Formuláře
✓ Strukturu moderní webové stránky
### CSS:
✓ Grid & Flexbox
✓ Positioning (všechny typy)
✓ Media queries
✓ CSS proměnné
✓ Jednotky (rem, em, vh, vw)
✓ Gradienty, shadows, transitions
✓ Animations
✓ Pokročilé selektory
### JavaScript:
✓ addEventListener
✓ DOM manipulace
✓ Form validation
✓ Event handling
✓ Podmínky a cykly
✓ Funkce
## 🎨 Design inspirace:
- https://www.awwwards.com/
- https://dribbble.com/
- Bootstrap examples (ale NEPOUŽÍVEJTE Bootstrap!)
## ⏱️ Odhadovaný čas: 4-6 hodin
## 🏆 Bonus úkoly (nepovinné):
1. Přidejte animaci AOS (Animate On Scroll) - při scrollování prvky plynule přijíždějí
2. Implementujte newsletter signup s AJAX (fake API endpoint)
3. Vytvořte carousel/slider pro testimonials (bez knihoven!)
4. Přidejte Easter egg (např. Konami kód)
5. PWA features (manifest.json, service worker)
## 📚 Co se naučíte pro Bootstrap:
Po dokončení tohoto projektu budete rozumět:
- Jak funguje responzivní grid systém → Bootstrap grid
- Jak fungují utility třídy → Bootstrap utilities
- Jak se stylují komponenty → Bootstrap components
- Jak funguje JavaScript interaktivita → Bootstrap JS
- Mobile-first přístup → Bootstrap philosophy
## 🚀 Po dokončení:
Gratulujeme! Jste připraveni na Bootstrap. Bootstrap vám nyní ušetří čas tím, že poskytuje:
- Předpřipravený grid systém (místo vašeho CSS Grid/Flexbox)
- Předpřipravené komponenty (tlačítka, karty, navigace)
- Předpřipravené utility třídy (margin, padding, colors)
- Responzivitu "out of the box"
Ale díky tomuto projektu rozumíte, co se děje "pod kapotou"!

42
AI_extra_material/ai_04_prep_bootstrap/css/animations.css

@ -0,0 +1,42 @@
/* AI 04 - CSS Animace */
/* ============================================
KEYFRAME ANIMATIONS
============================================ */
/* TODO: FadeIn animace */
@keyframes fadeIn {
/* from { opacity: 0; } */
/* to { opacity: 1; } */
}
/* TODO: SlideIn animace */
@keyframes slideInUp {
/* from { transform: translateY(50px); opacity: 0; } */
/* to { transform: translateY(0); opacity: 1; } */
}
/* TODO: Bounce animace */
@keyframes bounce {
/* 0%, 20%, 50%, 80%, 100% { transform: translateY(0); } */
/* 40% { transform: translateY(-20px); } */
/* 60% { transform: translateY(-10px); } */
}
/* TODO: Pulse animace (pro tlačítka) */
@keyframes pulse {
/* 0% { transform: scale(1); } */
/* 50% { transform: scale(1.05); } */
/* 100% { transform: scale(1); } */
}
/* TODO: Shake animace (pro chyby) */
@keyframes shake {
}
/* ============================================
UTILITY TŘÍDY PRO ANIMACE
============================================ */
/* TODO: Přidejte třídy jako .fade-in, .slide-in, atd. */

131
AI_extra_material/ai_04_prep_bootstrap/css/style.css

@ -0,0 +1,131 @@
/* AI 04 - Komplexní Bootstrap Prep Projekt */
/* ============================================
CSS PROMĚNNÉ (Custom Properties)
============================================ */
:root {
/* Barvy */
--primary-color: #667eea;
--secondary-color: #764ba2;
--success-color: #2ecc71;
--danger-color: #e74c3c;
--text-color: #333;
--text-light: #666;
--bg-color: #f8f9fa;
--white: #ffffff;
/* Spacing */
--spacing-xs: 0.5rem;
--spacing-sm: 1rem;
--spacing-md: 2rem;
--spacing-lg: 4rem;
--spacing-xl: 6rem;
/* Typography */
--font-primary: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
--font-size-base: 1rem;
--font-size-lg: 1.25rem;
--font-size-xl: 2rem;
--font-size-xxl: 3rem;
/* Breakpoints (pro JavaScript) */
--breakpoint-sm: 480px;
--breakpoint-md: 768px;
--breakpoint-lg: 1024px;
}
/* ============================================
RESET & BASE STYLES
============================================ */
/* TODO: Přidejte reset styly */
/* ============================================
NAVIGACE (position: fixed)
============================================ */
/* TODO: Vytvořte fixní navigaci nahoře */
/* ============================================
HEADER / HERO SEKCE
============================================ */
/* TODO: Hero sekce s gradientem, vycentrovaný text */
/* ============================================
FEATURES SEKCE (CSS GRID)
============================================ */
/* TODO: Grid layout pro features */
/* Desktop: 3 sloupce */
/* Tablet: 2 sloupce */
/* Mobil: 1 sloupec */
/* ============================================
PRICING SEKCE (CSS GRID + POSITIONING)
============================================ */
/* TODO: Grid layout pro cenové karty */
/* Použijte position: relative pro kontejner */
/* Použijte position: absolute pro "NEJLEPŠÍ VOLBA!" badge */
/* ============================================
TESTIMONIALS SEKCE (FLEXBOX)
============================================ */
/* TODO: Flex layout s flex-wrap */
/* ============================================
CONTACT SEKCE (FORMULÁŘ)
============================================ */
/* TODO: Styling formuláře s validačními stavy */
/* ============================================
ASIDE (position: sticky)
============================================ */
/* TODO: Sticky sidebar */
/* ============================================
FOOTER
============================================ */
/* TODO: Footer s flexboxem */
/* ============================================
SCROLL TO TOP BUTTON
============================================ */
/* TODO: Button pro scroll nahoru (position: fixed) */
/* ============================================
POKROČILÉ SELEKTORY
============================================ */
/* TODO: Použijte nth-child pro alternativní styling */
/* .feature-card:nth-child(even) {} */
/* TODO: Použijte ::before a ::after pro dekoraci */
/* TODO: Styling externích odkazů */
/* a[href^="http"] {} */
/* ============================================
MEDIA QUERIES - RESPONZIVITA
============================================ */
/* Mobile First! */
/* Tablet - 768px */
@media screen and (min-width: 768px) {
/* TODO */
}
/* Desktop - 1024px */
@media screen and (min-width: 1024px) {
/* TODO */
}

61
AI_extra_material/ai_04_prep_bootstrap/index.html

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="FitPro - Vaše cesta k lepší kondici">
<title>FitPro - Fitness Aplikace</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/animations.css">
</head>
<body>
<!-- TODO: Začněte zde vytvářet landing page -->
<!-- 1. NAVIGACE (position: fixed) -->
<!-- nav#navbar -->
<!-- 2. HEADER / HERO SEKCE -->
<!-- header#hero -->
<!-- 3. MAIN - Hlavní obsah -->
<!-- <main> -->
<!-- 3a. FEATURES SEKCE (CSS Grid) -->
<!-- section#features -->
<!-- 3b. PRICING SEKCE (CSS Grid) -->
<!-- section#pricing -->
<!-- 3c. TESTIMONIALS SEKCE (Flexbox) -->
<!-- section#testimonials -->
<!-- 3d. KONTAKT SEKCE (Formulář s validací) -->
<!-- section#contact -->
<!-- </main> -->
<!-- 4. ASIDE (position: sticky) -->
<!-- aside#quicklinks -->
<!-- 5. FOOTER -->
<!-- footer -->
<!-- 6. SCROLL TO TOP BUTTON (skrytý, zobrazí se při scrollování) -->
<!-- <button id="scrollToTop" class="scroll-top-btn">↑</button> -->
<!-- JavaScript soubory -->
<script src="js/validation.js"></script>
<script src="js/scroll.js"></script>
<script src="js/main.js"></script>
</body>
</html>

37
AI_extra_material/ai_04_prep_bootstrap/js/main.js

@ -0,0 +1,37 @@
// AI 04 - Main JavaScript
console.log("Main.js načten");
// ========================================
// PRICING TOGGLE (měsíční/roční)
// ========================================
// TODO: Implementujte přepínání mezi měsíčními a ročními cenami
// ========================================
// FAQ ACCORDION
// ========================================
// TODO: Implementujte accordion (kliknutí otevře/zavře odpověď)
// ========================================
// MODAL OKNO
// ========================================
// TODO: Implementujte modal okno pro "Více informací"
// ========================================
// COUNTER ANIMACE
// ========================================
// TODO: Animujte čísla od 0 do cílové hodnoty
// ========================================
// DARK MODE TOGGLE (BONUS)
// ========================================
// TODO: Implementujte přepínání mezi světlým a tmavým režimem

36
AI_extra_material/ai_04_prep_bootstrap/js/scroll.js

@ -0,0 +1,36 @@
// AI 04 - Scroll efekty
console.log("Scroll.js načten");
// ========================================
// SMOOTH SCROLL K SEKCÍM
// ========================================
// TODO: Implementujte smooth scroll při kliknutí na menu linky
// document.querySelectorAll('a[href^="#"]').forEach(anchor => {
// anchor.addEventListener('click', function (e) {
// e.preventDefault();
// // ... smooth scroll
// });
// });
// ========================================
// SCROLL TO TOP BUTTON
// ========================================
// TODO: Zobrazit/skrýt "Scroll to top" tlačítko při scrollování
// ========================================
// ZMĚNA NAVIGACE PŘI SCROLLOVÁNÍ
// ========================================
// TODO: Změnit barvu/styl navigace když uživatel scrolluje dolů
// ========================================
// ANIMATE ON SCROLL (BONUS)
// ========================================
// TODO: Přidejte třídu "visible" elementům když se dostanou do viewportu

48
AI_extra_material/ai_04_prep_bootstrap/js/validation.js

@ -0,0 +1,48 @@
// AI 04 - Validace formuláře
console.log("Validation.js načten");
// TODO: Implementujte validaci kontaktního formuláře
// Požadavky:
// - Jméno: min 3 znaky
// - Email: validní formát
// - Zpráva: min 10 znaků
// - Real-time validace pomocí addEventListener
// - Visual feedback (červená/zelená border)
// ========================================
// ZÍSKÁNÍ REFERENCÍ NA ELEMENTY
// ========================================
// TODO: const contactForm = document.getElementById("contactForm");
// ========================================
// EVENT LISTENERS
// ========================================
// TODO: Přidejte event listenery pro input eventy
// ========================================
// VALIDAČNÍ FUNKCE
// ========================================
// TODO: function validateContactName() {}
// TODO: function validateContactEmail() {}
// TODO: function validateContactMessage() {}
// ========================================
// HELPER FUNKCE
// ========================================
// TODO: function showError(element, message) {}
// TODO: function showSuccess(element) {}
// ========================================
// SUBMIT HANDLER
// ========================================
// TODO: function handleContactSubmit(e) {}

129
README.md

@ -6,6 +6,20 @@ Tento repozitář obsahuje **kódy a příklady z hodin** - materiály pro výuk
--- ---
## 🗺️ Rychlá Navigace
- 📖 [Základní lekce (01-11)](#-část-i-základy-webových-technologií-lekce-01-11)
- 🎨 [CSS Grid (12)](#-část-ii-css-grid-lekce-12)
- 🎯 [Bootstrap (13-17)](#-část-iii-bootstrap-framework-lekce-13-17)
- 🚀 [Pokročilé (18-20)](#-část-iv-pokročilé-techniky-lekce-18-20)
- 📁 [Bonusové materiály](#-bonusové-materiály)
- 💻 [VS Code Setup](#-vývojové-prostředí---visual-studio-code)
- 🛠️ [Jak pracovat s materiály](#️-jak-pracovat-s-materiály)
- 💡 [Tipy pro úspěch](#-tipy-pro-úspěch)
- 🆘 [Pomoc](#-když-si-nevíte-rady)
---
## 🚀 Rychlý Start ## 🚀 Rychlý Start
### Pro nové studenty: ### Pro nové studenty:
@ -39,7 +53,7 @@ Tento repozitář obsahuje **kódy a příklady z hodin** - materiály pro výuk
| Lekce | Téma | Zaměření | | Lekce | Téma | Zaměření |
|-------|------|----------| |-------|------|----------|
| **01** | [Úvod do HTML](01_uvod/) | HTML struktura, základní tagy, seznamy, tabulky | | **01** | [Úvod do HTML](01_uvod/) | HTML struktura, základní tagy, seznamy, tabulky |
| **02** | [Formuláře](02/) | Input fieldy, validace, form atributy |
| **02** | [Pokročilé HTML](02/) | Tabulky, seznamy, Emmet zkratky |
| **03** | [Úvod do CSS](03_css_uvod/) | Selektory, box model, barvy, fonty | | **03** | [Úvod do CSS](03_css_uvod/) | Selektory, box model, barvy, fonty |
| **04** | [CSS Layout](04_layout/) | Display, margin, padding, základní layout | | **04** | [CSS Layout](04_layout/) | Display, margin, padding, základní layout |
| **05** | [JavaScript Intro](05_js_intro/) | Proměnné, datové typy, operátory, funkce | | **05** | [JavaScript Intro](05_js_intro/) | Proměnné, datové typy, operátory, funkce |
@ -77,6 +91,10 @@ Tento repozitář obsahuje **kódy a příklady z hodin** - materiály pro výuk
### 📁 Bonusové Materiály ### 📁 Bonusové Materiály
- **[novyprojekt_bootstrap](novyprojekt_bootstrap/)** - Šablona pro nové Bootstrap projekty - **[novyprojekt_bootstrap](novyprojekt_bootstrap/)** - Šablona pro nové Bootstrap projekty
- **[AI_extra_material](AI_extra_material/)** - Doplňkové studijní materiály
- Bootstrap form validace ukázky
- XSS bezpečnostní demo
- Informační materiály pro učitele (ISP, hodnocení)
--- ---
@ -165,6 +183,7 @@ Otevřete Settings (`Ctrl + ,`) a nastavte:
Každá lekce obvykle obsahuje: Každá lekce obvykle obsahuje:
``` ```
XX_nazev_lekce/ XX_nazev_lekce/
├── README.md # Průvodce lekcí s vysvětlením
├── index.html # Hlavní HTML soubor s příklady ├── index.html # Hlavní HTML soubor s příklady
├── style.css # CSS styly (nebo složka css/) ├── style.css # CSS styly (nebo složka css/)
├── script.js # JavaScript (nebo složka js/) ├── script.js # JavaScript (nebo složka js/)
@ -176,11 +195,12 @@ XX_nazev_lekce/
### Postup Práce ### Postup Práce
1. **Prostudujte kód z hodiny** - Otevřete `index.html` a projděte si kód
2. **Experimentujte** - Měňte hodnoty, zkoušejte vlastní úpravy
3. **Použijte Live Server** - Pravé tlačítko → "Open with Live Server"
4. **Testujte v prohlížeči** - Používejte Developer Tools (F12)
5. **Commitujte změny** - Používejte Git pro verzování
1. **Přečtěte si README.md** - každá složka má průvodce s vysvětlením
2. **Prostudujte kód z hodiny** - Otevřete `index.html` a projděte si kód
3. **Experimentujte** - Měňte hodnoty, zkoušejte vlastní úpravy
4. **Použijte Live Server** - Pravé tlačítko → "Open with Live Server"
5. **Testujte v prohlížeči** - Používejte Developer Tools (F12)
6. **Commitujte změny** - Používejte Git pro verzování
--- ---
@ -215,11 +235,12 @@ XX_nazev_lekce/
### Zdroje Pomoci ### Zdroje Pomoci
1. **Developer Tools** (F12) - konzole ukazuje chyby
2. **Předchozí lekce** - příklady použití
3. **Komentáře v kódu** - často tam je vysvětlení
4. **Spolužáci** - diskutujte společně
5. **Učitel** - konzultační hodiny
1. **README.md v každé složce** - obsahuje vysvětlení a ukázky
2. **Developer Tools** (F12) - konzole ukazuje chyby
3. **Předchozí lekce** - příklady použití
4. **Komentáře v kódu** - často tam je vysvětlení
5. **Spolužáci** - diskutujte společně
6. **Učitel** - konzultační hodiny
### Časté Chyby a Řešení ### Časté Chyby a Řešení
@ -249,10 +270,11 @@ XX_nazev_lekce/
### Pro Začátečníky ### Pro Začátečníky
1. **Postupujte chronologicky** - Každá lekce navazuje na předchozí 1. **Postupujte chronologicky** - Každá lekce navazuje na předchozí
2. **Nezbrkejte se** - Raději pomalu, ale pořádně
3. **Experimentujte** - Zkoušejte vlastní úpravy kódu
4. **Používejte DevTools** - F12 v prohlížeči je váš kamarád
5. **Pište si poznámky** - Co jste se naučili
2. **Čtěte README.md** - Každá složka má průvodce s vysvětlením
3. **Nezbrkejte se** - Raději pomalu, ale pořádně
4. **Experimentujte** - Zkoušejte vlastní úpravy kódu
5. **Používejte DevTools** - F12 v prohlížeči je váš kamarád
6. **Pište si poznámky** - Co jste se naučili
### Při Vývoji Projektů ### Při Vývoji Projektů
@ -277,65 +299,11 @@ div#header → <div id="header"></div>
--- ---
## 🎯 Co se Naučíte
Po dokončení celého kurzu budete umět:
### HTML
✅ Vytvořit sémanticky správnou strukturu stránky
✅ Pracovat s formuláři a validací
✅ Používat HTML5 elementy (`nav`, `section`, `article`, `aside`)
✅ Implementovat accessibility best practices
### CSS
✅ Stylovat moderní responzivní webové stránky
✅ Používat Flexbox i CSS Grid
✅ Vytvářet animace a transitions
✅ Pracovat s různými jednotkami (px, rem, em, vh, vw)
✅ Používat pokročilé selektory a pseudo-třídy
✅ Psát responzivní CSS s media queries
### JavaScript
✅ Manipulovat s DOM
✅ Zpracovávat uživatelské události
✅ Validovat formuláře
✅ Pracovat s JSON daty
✅ Používat fetch API pro AJAX
✅ Psát čistý, čitelný kód
### Bootstrap
✅ Používat Bootstrap Grid System
✅ Implementovat Bootstrap komponenty
✅ Přizpůsobovat Bootstrap svým potřebám
✅ Rozumět, co framework dělá "pod kapotou"
✅ Rozhodnout, kdy Bootstrap použít a kdy ne
---
## 🌟 Co Dál?
Po dokončení tohoto kurzu budete pokračovat v:
### **Node.js**
- JavaScript na serveru
- NPM (Node Package Manager)
- Express.js framework
- REST API
- Práce s databázemi
### **Vue.js**
- Moderní JavaScript framework
- Komponenty a reaktivita
- Vue Router
- Vuex (state management)
- Single Page Applications (SPA)
---
## 📖 Důležité Poznámky ## 📖 Důležité Poznámky
### Pro Studenty ### Pro Studenty
- 📝 Všechny materiály jsou v **češtině** - 📝 Všechny materiály jsou v **češtině**
- 📚 **Každá složka má README.md** s vysvětlením a ukázkami
- 💻 Žádný build proces - soubory otevřete přímo v prohlížeči - 💻 Žádný build proces - soubory otevřete přímo v prohlížeči
- 🔄 Používejte Git pro verzování vašeho pokroku - 🔄 Používejte Git pro verzování vašeho pokroku
- 🤝 Spolupracujte, ale nekopírujte řešení - 🤝 Spolupracujte, ale nekopírujte řešení
@ -348,15 +316,6 @@ Tento kurz učí **postupně a důkladně**. Začínáte s čistým HTML a CSS,
--- ---
## 📞 Kontakt
Při problémech nebo dotazech:
- 💬 Konzultační hodiny s vyučujícím
- 📧 Školní email
- 👥 Diskuze se spolužáky
---
## 📜 Licence a Použití ## 📜 Licence a Použití
Materiály jsou určené pro výukové účely studentů kurzu Webové Technologie. Materiály jsou určené pro výukové účely studentů kurzu Webové Technologie.
@ -366,15 +325,3 @@ Materiály jsou určené pro výukové účely studentů kurzu Webové Technolog
**Hodně štěstí s učením! 🚀** **Hodně štěstí s učením! 🚀**
*Vytvořeno pro studenty 3. ročníku IT - Školní rok 2025/2026* *Vytvořeno pro studenty 3. ročníku IT - Školní rok 2025/2026*
---
## 🗺️ Rychlá Navigace
- 📖 [Základní lekce (01-11)](#část-i-základy-webových-technologií-lekce-01-11)
- 🎨 [CSS Grid (12)](#část-ii-css-grid-lekce-12)
- 🎯 [Bootstrap (13-17)](#část-iii-bootstrap-framework-lekce-13-17)
- 🚀 [Pokročilé (18-20)](#část-iv-pokročilé-techniky-lekce-18-20)
- 💻 [VS Code Setup](#vývojové-prostředí---visual-studio-code)
- 💡 [Tipy pro úspěch](#tipy-pro-úspěch)
- 🆘 [Pomoc](#když-si-nevíte-rady)

177
novyprojekt_bootstrap/README.md

@ -0,0 +1,177 @@
# Nový Bootstrap Projekt
## 🎯 Účel projektu
Tento projekt slouží jako **prázdná šablona** pro vytváření nových Bootstrap projektů. Obsahuje základní připojení Bootstrap CSS a JS.
## 📚 Co projekt obsahuje
- **Bootstrap 5.x** - lokální soubory CSS a JS
- **Základní HTML struktura** - připravená pro vývoj
- **Viewport meta tag** - pro responzivitu
## 📂 Soubory v projektu
- `index.html` - základní HTML s připojeným Bootstrapem
- `css/bootstrap.css` - Bootstrap CSS (lokální soubor)
- `js/bootstrap.js` - Bootstrap JavaScript (lokální soubor)
## 🚀 Jak použít tento projekt
### Krok 1: Zkopírujte složku
```bash
# Zkopírujte celou složku novyprojekt_bootstrap
# Přejmenujte na název vašeho projektu, např.:
- muj_novy_projekt/
- portfolio_stranky/
- eshop_projekt/
```
### Krok 2: Upravte index.html
```html
<!DOCTYPE html>
<html lang="cs"> <!-- změňte jazyk na cs -->
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Můj projekt</title> <!-- změňte title -->
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
<div class="container">
<h1 class="display-1">Hello World with Bootstrap!</h1>
<!-- Začněte psát váš kód zde -->
</div>
<script src="js/bootstrap.js"></script>
</body>
</html>
```
### Krok 3: Začněte vyvíjet
**Přidejte Bootstrap komponenty:**
```html
<!-- Navigace -->
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="#">Logo</a>
</div>
</nav>
<!-- Grid -->
<div class="container">
<div class="row">
<div class="col-md-6">Sloupec 1</div>
<div class="col-md-6">Sloupec 2</div>
</div>
</div>
<!-- Tlačítka -->
<button class="btn btn-primary">Primary</button>
<button class="btn btn-success">Success</button>
<!-- Karty -->
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">Název karty</h5>
<p class="card-text">Text karty</p>
<a href="#" class="btn btn-primary">Tlačítko</a>
</div>
</div>
```
## 💡 Užitečné Bootstrap třídy
### Container a Grid:
```html
<div class="container"> <!-- Fixní šířka, centrovaný -->
<div class="container-fluid"> <!-- 100% šířka -->
<div class="row"> <!-- Řádek -->
<div class="col-md-6"> <!-- 50% na tabletu+ -->
```
### Utility třídy:
```html
<!-- Margin a Padding -->
m-3 = margin všude
mt-2 = margin-top
px-4 = padding vlevo a vpravo
<!-- Barvy -->
text-primary = modrý text
bg-danger = červené pozadí
<!-- Display -->
d-flex = display: flex
d-none d-md-block = skryto na mobilu, zobrazeno na tabletu+
```
### Komponenty:
```html
<!-- Buttons -->
<button class="btn btn-primary">Primary</button>
<!-- Alerts -->
<div class="alert alert-success">Success!</div>
<!-- Cards -->
<div class="card">...</div>
<!-- Modal -->
<button data-bs-toggle="modal" data-bs-target="#myModal">
Open Modal
</button>
```
## 🔗 Bootstrap dokumentace
- **Oficiální dokumentace:** https://getbootstrap.com/docs/5.3/
- **Bootstrap Icons:** https://icons.getbootstrap.com/
- **Bootstrap Examples:** https://getbootstrap.com/docs/5.3/examples/
## 📚 Související lekce
Před použitím tohoto projektu se ujistěte, že jste prošli:
- **13_bootstrap_intro** - úvod do Bootstrapu
- **14_bootstrap_layout** - Bootstrap layout
- **15_bootstrap_components** - Bootstrap komponenty
## 💡 Tip pro studenty
**Kdy použít tento projekt:**
- ✅ Nový Bootstrap projekt od nuly
- ✅ Prototypování webové stránky
- ✅ Cvičení Bootstrap komponent
- ✅ Školní projekty
**Alternativa - CDN (online Bootstrap):**
```html
<!-- Místo lokálních souborů můžete použít CDN -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
```
**Výhody lokálních souborů:**
- Funguje offline
- Rychlejší (není potřeba stahovat z internetu)
**Výhody CDN:**
- Menší velikost projektu
- Možná už v cache prohlížeče
## ⚠️ Důležité poznámky
1. **Bootstrap.js vyžaduje** - carousel, modal, dropdown fungují jen s připojeným JS
2. **Viewport meta tag je povinný** - bez něj responzivita nebude fungovat
3. **jQuery není potřeba** - Bootstrap 5 už jQuery nepotřebuje
## 🎯 Další kroky
1. Prozkoumejte [Bootstrap dokumentaci](https://getbootstrap.com/)
2. Vyzkoušejte různé komponenty
3. Vytvořte vlastní projekt pomocí této šablony
4. Experimentujte s utility třídami
Hodně štěstí s vaším projektem! 🚀
Loading…
Cancel
Save