Przejdź do głównej treści
INF.03-08-25.06-SGCzerwiec 2025 · 64 kroki · ok. 119 min

Rozwiązanie krok po kroku: Portal hobbystyczny o smokach

Budujemy portal hobbystyczny o smokach: baza smoki z czterema kwerendami, grafika przeskalowana do 300 px wysokości, strona smoki.php ze stylami w styl.css, przełączanie sekcji w JavaScript i dwa skrypty PHP (lista krajów i tabela smoków wybranego kraju).

Kroki idą zdanie po zdaniu za treścią arkusza - każdy zaczyna się cytatem wymagania, a kod obok pokazuje dokładnie te linie, które je spełniają. Kolejność jest taka, jak warto pracować na egzaminie: najpierw baza i zrzuty (pewne punkty), potem struktura strony, style, JavaScript, na końcu PHP.

Grafiki, opisy i baza danych pochodzą z prawdziwego archiwum pliki7 (załącznik do pobrania na stronie arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robisz je sam, z całego ekranu.

Etapy pracy (64 kroki to siedem krótkich etapów):

  1. Baza danych - kroki 1-7 (kryteria R.1, 6 punktów)
  2. Grafika i strona HTML - kroki 8-30 (R.2 i R.3, 15 punktów)
  3. Styl CSS - kroki 31-42 (R.4, 10 punktów)
  4. JavaScript - kroki 43-49 (R.5.6 - R.5.10)
  5. Skrypty PHP - kroki 50-59 (R.5.1 - R.5.5)
  6. Nasłuchiwacze zamiast onclick - kroki 60-63 (wariant, poza kluczem)
  7. Oddanie pracy - krok 64

Jak liczą się punkty. Klucz ma 41 kryteriów (R.1.1 - R.5.10), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 31 punktów - można stracić 10 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.

To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.
  1. Krok 1: Baza danych smoki

    Kryteria: R.1.1 ok. 2 min

    Arkusz: Utwórz bazę danych o nazwie smoki, z zestawem polskich znaków (np. utf8_polish_ci).

    W przeglądarce otwieramy http://localhost/phpmyadmin, klikamy Nowa w lewym panelu, wpisujemy nazwę smoki i z listy metod porównywania wybieramy utf8_polish_ci. Bez polskiego porównywania polskie litery mogłyby sortować się poza alfabetem (np. „ł” za „z”), a dane z importu mogłyby stracić ogonki.

    Typowe błędy

    Nazwa bazy musi być dokładnie smoki - skrypty PHP łączą się z bazą po nazwie, więc Smoki albo smok odetnie punkty także za skrypty.

  2. Krok 2: Import tabel z pliku bazasmoki.sql

    Kryteria: R.1.1 ok. 2 min

    Arkusz: Z rozpakowanego archiwum zaimportuj tabele z pliku bazasmoki.sql do utworzonej bazy.

    Wchodzimy do bazy smoki (musi być zaznaczona w lewym panelu), karta Import, Wybierz plik → bazasmoki.sql z rozpakowanego archiwum, Wykonaj.

    Po imporcie w bazie są trzy tabele z ilustracji 1: smok (id, nazwa, dlugosc, szerokosc, pochodzenie - 44 wiersze), parada (id, rok, liczba_widzow, atrakcje - 48 wierszy) i łącząca je udzial z kluczami obcymi id_smok i id_parada (127 wierszy). To relacja wiele do wielu - jeden smok bierze udział w wielu paradach, a w jednej paradzie idzie wiele smoków. Ta wiedza przyda się przy zapytaniu 3.

    Typowe błędy

    Import bez wcześniejszego wejścia do bazy smoki tworzy tabele w innej bazie (np. test) - zapytania w PHP nie znajdą wtedy tabeli smok.

  3. Krok 3: Zrzut ekranu import.jpg

    Kryteria: R.1.1 ok. 2 min

    Arkusz: Wykonaj zrzut ekranu po imporcie. Zapisz zrzut w formacie JPEG pod nazwą import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań.

    Klawisz Print Screen (cały ekran, nie Alt+PrtScr, który łapie tylko aktywne okno), wklejamy do edytora grafiki i zapisujemy jako import.jpg w folderze z numerem zdającego. Na zrzucie ma być widać komunikat phpMyAdmin o pomyślnym imporcie albo listę trzech tabel w bazie smoki - to dowód, że import się udał.

    Typowe błędy

    Wykadrowany zrzut (samo okno przeglądarki, bez paska zadań) nie jest oceniany - klucz mówi to wprost. Zrzut importu ma być w JPEG, zrzuty kwerend w PNG.

  4. Krok 4: Zapytanie 1: smoki z Polski

    Kryteria: R.1.2, R.1.3 ok. 4 min

    Arkusz: Zapytanie 1: wybierające jedynie nazwę, długość i szerokość smoka, dla smoków z Polski.

    Zakładka SQL w phpMyAdmin (przy zaznaczonej bazie smoki). Zapytanie czytamy klauzula po klauzuli:

    • SELECT nazwa, dlugosc, szerokosc - które kolumny ma zwrócić wynik. Słowo „jedynie” w arkuszu oznacza, że wymieniamy dokładnie te trzy; SELECT * nie spełnia warunku, bo zwraca też id i pochodzenie. Nazwy kolumn bierzemy z ilustracji 1 (bez polskich znaków, tak jak w tabeli).
    • FROM smok - z której tabeli.
    • WHERE pochodzenie = "Polska" - które wiersze: tylko te, w których kraj to Polska. Napis porównujemy w cudzysłowie.

    Wynik: dokładnie 23 rekordy o trzech kolumnach. Zapytanie od razu kopiujemy do pliku kwerendy.txt (zwykły edytor tekstu, np. Notatnik) i robimy zrzut całego ekranu z wynikiem: kw1.png.

    Typowe błędy

    WHERE pochodzenie = Polska bez cudzysłowu to błąd składni - napis w SQL zawsze w cudzysłowie albo apostrofach.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT nazwa, dlugosc, szerokosc FROM smok WHERE pochodzenie = "Polska";
    Podgląd strony po tym kroku Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: kraje pochodzenia bez powtórzeń

    Kryteria: R.1.4 ok. 3 min

    Arkusz: Zapytanie 2: wybierające niepowtarzające się kraje pochodzenia smoków, posortowane rosnąco według kraju pochodzenia.

    Klauzula po klauzuli:

    • SELECT DISTINCT pochodzenie - jedna kolumna, a DISTINCT usuwa powtórzenia: bez niego dostalibyśmy „Polska” 23 razy, po jednym na każdego polskiego smoka.
    • FROM smok - kraj pochodzenia jest w tabeli smoków.
    • ORDER BY pochodzenie - sortowanie po tej kolumnie. Rosnąco (A→Z) jest domyślne, więc ASC można pominąć; malejąco byłoby DESC.

    Wynik to pięć wierszy: Bułgaria, Chiny, Francja, Japonia, Polska. Zrzut: kw2.png.

    To samo zapytanie wyśle później skrypt 1, żeby wypełnić listę rozwijaną - warto je zapamiętać.

    Typowe błędy

    Klucz dopuszcza też GROUP BY pochodzenie zamiast DISTINCT (wtedy ORDER BY jest według klucza opcjonalne). DISTINCT jest jednak prostszy i dokładnie oddaje słowo „niepowtarzające się” z arkusza.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, dlugosc, szerokosc FROM smok WHERE pochodzenie = "Polska";
    
    -- Zapytanie 2
    SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;
    Podgląd strony po tym kroku Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: średnia długość smoków w paradach po 2005 roku

    Kryteria: R.1.5 ok. 6 min

    Arkusz: Zapytanie 3: wybierające jedynie rok z tabeli parada i obliczającą odpowiadającą mu średnią wartość długości z tabeli smok, nazwa kolumny (alias) „Średnia długość” tylko dla lat po 2005 roku. Należy posłużyć się relacją i zgrupować rekordy względem roku.

    Najtrudniejsze zapytanie arkusza. Rok jest w tabeli parada, długość w smok, a żadna z nich nie ma klucza do drugiej - łączy je tabela udzial (ilustracja 1). Klauzula po klauzuli:

    • SELECT rok, AVG(dlugosc) AS "Średnia długość" - rok i średnia z długości. AVG to funkcja grupująca: liczy jedną wartość z wielu wierszy. AS nadaje kolumnie wyniku nazwę (alias); alias ze spacją i polskimi znakami musi być w cudzysłowie.
    • FROM parada - zaczynamy od tabeli z rokiem.
    • JOIN udzial ON parada.id = udzial.id_parada - do każdej parady dokładamy jej wpisy z tabeli łączącej; ON mówi, po których kolumnach wiersze do siebie pasują (klucz główny parady = klucz obcy w udzial).
    • JOIN smok ON udzial.id_smok = smok.id - i do każdego wpisu dokładamy smoka, żeby mieć jego długość. Po dwóch złączeniach każdy wiersz to para „parada + smok, który w niej szedł”.
    • WHERE rok > 2005 - odrzucamy parady z 2005 i wcześniejsze przed liczeniem średniej. „Po 2005 roku” to >, nie >=.
    • GROUP BY rok - wiersze o tym samym roku zlewają się w jeden, a AVG liczy średnią osobno dla każdej grupy. Bez grupowania wyszłaby jedna liczba dla wszystkich lat.

    Oczekiwane 5 rekordów: 2006 (4,6), 2013 (7,6), 2014 (5,5), 2021 (7,625), 2025 (6,4091). Zrzut: kw3.png.

    Typowe błędy

    JOIN bez warunku ON daje iloczyn kartezjański i złą średnią. HAVING rok > 2005 też zadziała, ale warunek na zwykłej kolumnie to miejsce dla WHERE - HAVING jest dla warunków na wyniku funkcji grupujących (np. HAVING AVG(dlugosc) > 5).

    kwerendy.txt Tekst zmienione: 8 linii
    -- Zapytanie 1
    SELECT nazwa, dlugosc, szerokosc FROM smok WHERE pochodzenie = "Polska";
    
    -- Zapytanie 2
    SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;
    
    -- Zapytanie 3
    SELECT rok, AVG(dlugosc) AS "Średnia długość"
    FROM parada
    JOIN udzial ON parada.id = udzial.id_parada
    JOIN smok ON udzial.id_smok = smok.id
    WHERE rok > 2005
    GROUP BY rok;
    Podgląd strony po tym kroku Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: nowa kolumna w tabeli parada

    Kryteria: R.1.6 ok. 3 min

    Arkusz: Zapytanie 4: zmieniające strukturę tabeli parada, przez wstawienie nowej kolumny lokalizacja typu napisowego o maksymalnej długości 100 znaków.

    Zmiana struktury tabeli to ALTER TABLE (nie UPDATE, który zmienia dane). Typ napisowy o maksymalnej długości to VARCHAR(100). Zrzut kw4.png ma pokazać komunikat o pomyślnym wykonaniu albo kartę Struktura z nową kolumną.

    Plik kwerendy.txt zawiera teraz wszystkie cztery zapytania - sprawdź, że jest zapisany w folderze z numerem zdającego.

    Typowe błędy

    CHAR(100) to napis o stałej długości 100 znaków - arkusz mówi o długości maksymalnej, czyli VARCHAR.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT nazwa, dlugosc, szerokosc FROM smok WHERE pochodzenie = "Polska";
    
    -- Zapytanie 2
    SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;
    
    -- Zapytanie 3
    SELECT rok, AVG(dlugosc) AS "Średnia długość"
    FROM parada
    JOIN udzial ON parada.id = udzial.id_parada
    JOIN smok ON udzial.id_smok = smok.id
    WHERE rok > 2005
    GROUP BY rok;
    
    -- Zapytanie 4
    ALTER TABLE parada ADD COLUMN lokalizacja VARCHAR(100);
    Podgląd strony po tym kroku Podgląd strony po kroku 7
  8. Krok 8: Przeskalowanie grafiki smok1.jpg

    Kryteria: R.2.1 ok. 3 min

    Arkusz: Cechy grafiki smok1.jpg: przeskalowana z zachowaniem proporcji do wysokości 300 px.

    Plik smok1.jpg z archiwum to zdjęcie z aparatu: 3872 × 2592 px, 2,6 MB - za duże na stronę. W edytorze grafiki rastrowej (np. GIMP: Obraz → Skaluj obraz) wpisujemy wysokość 300 px przy zamkniętym łańcuchu proporcji. Szerokość przeliczy się sama na 448 px (3872 · 300 / 2592 = 448,1) - i dokładnie to sprawdza egzaminator (448 ±5 px). Zapisujemy jako smok1.jpg w folderze zdającego. Pozostałe dwa zdjęcia mają już 448 × 300 px - arkusz nie każe ich ruszać.

    Typowe błędy

    Rozłączony łańcuch proporcji = obraz rozciągnięty do 300 px wysokości przy starej szerokości. Wysokość się zgadza, punktu nie ma.

    Podgląd strony po tym kroku Podgląd strony po kroku 8
  9. Krok 9: Plik smoki.php w HTML5

    Kryteria: R.2.2 ok. 2 min

    Arkusz: Składa się ze strony o nazwie smoki.php. Zapisana w języku HTML5.

    W edytorze zaznaczającym składnię tworzymy plik smoki.php w folderze zdającego. Rozszerzenie .php, bo na końcu dojdą skrypty PHP - na razie to czysty HTML i przeglądarka pokaże go tak samo jak .html.

    Pierwsza linia <!DOCTYPE html> mówi przeglądarce, że dokument jest w HTML5. Dalej szkielet każdej strony: <html>, a w nim <head> (informacje o stronie) i <body> (to, co widać w oknie).

    Typowe błędy

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0..."> to deklaracja XHTML, nie HTML5 - klucz sprawdza krótką postać HTML5.

    smoki.php PHP nowy plik
    <!DOCTYPE html>
    <html>
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  10. Krok 10: Język strony

    Kryteria: R.2.2 ok. 1 min

    Arkusz: Zadeklarowany polski język zawartości witryny.

    Atrybut lang="pl" w znaczniku <html>. Czytnik ekranu czyta wtedy tekst polską wymową, a przeglądarka dobiera słownik i dzielenie wyrazów. Na stronie nic się nie zmienia - to informacja dla programów, nie dla oka.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  11. Krok 11: Kodowanie polskich znaków

    Kryteria: R.2.2 ok. 1 min

    Arkusz: Jawnie zastosowany właściwy standard kodowania polskich znaków.

    <meta charset="UTF-8"> jako pierwsza rzecz w <head>. „Jawnie” znaczy: wpisane w kodzie, a nie zdane na domysł przeglądarki. Bez tej linii „Długość” może wyświetlić się jako „DÅ‚ugość”. Plik trzeba też zapisać w UTF-8 - większość edytorów robi to domyślnie.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  12. Krok 12: Tytuł strony

    Kryteria: R.2.2 ok. 1 min

    Arkusz: Tytuł strony „Smoki”.

    <title> w <head> - to napis na karcie przeglądarki i w zakładkach, nie nagłówek na stronie. Klucz sprawdza dokładnie tekst „Smoki”.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  13. Krok 13: Podpięcie arkusza stylów

    Kryteria: R.3.2 ok. 1 min

    Arkusz: Arkusz stylów w pliku o nazwie styl.css prawidłowo połączony z kodem strony.

    <link rel="stylesheet" href="styl.css"> w <head>. Plik styl.css jeszcze nie istnieje - napiszemy go po HTML - ale połączenie może już być: gdy plik się pojawi w tym samym folderze, style zadziałają bez zmian w HTML.

    Typowe błędy

    <link> to znacznik pusty - w HTML5 bez </link> i bez ukośnika />. Bez rel="stylesheet" przeglądarka nie potraktuje pliku jako stylów.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  14. Krok 14: Bloki semantyczne

    Kryteria: R.2.3 ok. 2 min

    Arkusz: Podział strony na bloki zrealizowany za pomocą semantycznych znaczników bloków języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków na stronie był zgodny z ilustracją 3.

    Z ilustracji 3: na górze blok nagłówkowy, pod nim obok siebie blok nawigacyjny i blok główny, na dole stopka. Semantyczne odpowiedniki z tabeli 4 arkusza to <header>, <nav>, <main> i <footer> - nie <div> z klasami. Na razie są puste. To, że nawigacja i część główna staną obok siebie, zrobi dopiero CSS.

    Typowe błędy

    Cztery zwykłe <div> z identyfikatorami w rodzaju naglowek, nawigacja wyglądają na stronie identycznie, ale kryterium R.2.3 wymaga znaczników semantycznych - to jest sprawdzane w kodzie źródłowym.

    smoki.php PHP zmienione: 8 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
        </header>
        <nav>
        </nav>
        <main>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  15. Krok 15: Nagłówek strony

    Kryteria: R.2.5 ok. 1 min

    Arkusz: Zawartość bloku nagłówkowego: nagłówek drugiego stopnia o treści „Poznaj smoki!”.

    Drugiego stopnia to <h2> - nie <h1>, choć na pierwszym nagłówku strony wydaje się naturalniejszy. Egzaminator sprawdza dokładnie ten znacznik, który wskazał arkusz. Wykrzyknik należy do treści.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
        </nav>
        <main>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  16. Krok 16: Blok 1 „Baza” w nawigacji

    Kryteria: R.2.4 ok. 1 min

    Arkusz: Zawartość bloku nawigacyjnego to trzy bloki: blok 1 z treścią „Baza”, gdy zostanie kliknięty jest wywoływana funkcja JavaScript.

    W <nav> dajemy <div> z tekstem „Baza”. Dostaje id="block1" - po tym identyfikatorze złapie go JavaScript i osobny styl (tylko blok 1 ma inne tło) - oraz klasę block, wspólną dla trzech bloków, żeby nie powtarzać stylów trzy razy.

    Nazwy identyfikatorów, klas, zmiennych i funkcji piszemy w tym rozwiązaniu po angielsku - arkusz dopuszcza polski lub angielski, ale wymaga konsekwencji i znaczących nazw. Wyjątkiem są nazwy narzucone przez arkusz (smoki.php, styl.css, kolumny bazy).

    Wywołanie funkcji po kliknięciu dopiszemy, gdy będzie gotowy skrypt. Teraz budujemy samą strukturę.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
        </nav>
        <main>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  17. Krok 17: Blok 2 „Opisy”

    Kryteria: R.2.4 ok. 1 min

    Arkusz: Blok 2 z treścią „Opisy”, gdy zostanie kliknięty jest wywoływana funkcja JavaScript.

    Tak samo jak blok 1: id="block2" i klasa block. Identyfikatory numerujemy konsekwentnie (block1, block2, block3), bo skrypt będzie je składał z liczby.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
        </nav>
        <main>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  18. Krok 18: Blok 3 „Galeria”

    Kryteria: R.2.4 ok. 1 min

    Arkusz: Blok 3 z treścią „Galeria”, gdy zostanie kliknięty jest wywoływana funkcja JavaScript.

    Trzeci blok: id="block3", klasa block. W nawigacji są teraz trzy bloki - tyle wymaga kryterium R.2.4.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  19. Krok 19: Sekcja 1 z nagłówkiem

    Kryteria: R.2.4, R.2.5 ok. 1 min

    Arkusz: Zawartość bloku głównego to trzy sekcje (w jednym momencie jest widoczna tylko jedna sekcja). Sekcja 1: nagłówek trzeciego stopnia o treści „Baza Smoków”.

    W <main> dajemy <section id="section1"> z nagłówkiem <h3> (trzeciego stopnia). Identyfikator jest potrzebny, bo JavaScript będzie przełączał widoczność sekcji. „Widoczna tylko jedna” zrobią CSS (ukrycie sekcji 2 i 3 na starcie) i JS (przełączanie) - HTML zawiera wszystkie trzy.

    smoki.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  20. Krok 20: Formularz

    Kryteria: R.3.3 ok. 1 min

    Arkusz: Formularz wysyłający dane do tego samego pliku metodą bezpieczną, z elementami: lista rozwijana, przycisk.

    „Metoda bezpieczna” to POST - dane nie pojawiają się w adresie strony, jak przy GET. „Do tego samego pliku” to brak atrybutu action (przeglądarka wysyła wtedy formularz na adres bieżącej strony) albo action="smoki.php" - klucz przyjmuje oba warianty.

    Typowe błędy

    method="get" (albo brak method, bo GET jest domyślny) wyśle kraj w adresie - to nie jest metoda bezpieczna i skrypt czytający $_POST nic nie dostanie.

    smoki.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                </form>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  21. Krok 21: Lista rozwijana

    Kryteria: R.2.10 ok. 1 min

    Arkusz: Lista rozwijana wypełniona przez skrypt 1.

    <select> z atrybutem name="country" - pod tą nazwą wybrana wartość trafi do PHP jako $_POST['country']. Opcje <option> wstawi skrypt 1 na podstawie zapytania 2, więc lista na razie jest pusta i w podglądzie wygląda na wąską.

    Typowe błędy

    Bez atrybutu name przeglądarka w ogóle nie wyśle wartości listy - formularz dojdzie pusty i skrypt 2 nie będzie miał po czym filtrować.

    smoki.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                </form>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  22. Krok 22: Przycisk „Szukaj”

    Kryteria: R.2.10, R.3.4 ok. 1 min

    Arkusz: Przycisk „Szukaj”, wysyłający dane z formularza do skryptu 2.

    <button type="submit"> wewnątrz formularza wysyła go po kliknięciu. Typ submit jest dla <button> w formularzu domyślny, ale wpisany wprost nie zostawia wątpliwości. Klucz przyjmuje też <input type="submit" value="Szukaj">.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  23. Krok 23: Tabela z wierszem nagłówkowym

    Kryteria: R.2.8, R.2.9 ok. 2 min

    Arkusz: Tabela o trzech kolumnach. Pierwszy wiersz jest wierszem z komórkami nagłówkowymi: „Nazwa”, „Długość”, „Szerokość”. Kolejne wiersze są wypełnione przez skrypt 2.

    <table> z jednym wierszem <tr>, w którym są komórki nagłówkowe <th> - nie <td>. To osobne kryterium (R.2.9) i częsta strata punktu. Kolejne wiersze <tr> z komórkami <td> dopisze skrypt 2, więc w HTML jest tylko nagłówek.

    smoki.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  24. Krok 24: Sekcja 2 z nagłówkiem

    Kryteria: R.2.4, R.2.5 ok. 1 min

    Arkusz: Sekcja 2: nagłówek trzeciego stopnia o treści „Opisy smoków”.

    <section id="section2"> z <h3>. W podglądzie widać ją pod sekcją 1 - ukryje ją CSS w dalszej części, a pokaże JavaScript po kliknięciu „Opisy”.

    smoki.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  25. Krok 25: Lista definicji z opisami smoków

    Kryteria: R.2.7 ok. 3 min

    Arkusz: Lista definicji wypełniona danymi, które należy skopiować z pliku opis.txt. Nazwa smoka jest terminem, a pozostałe dane - opisem definicji, zgodnie z ilustracją 5.

    Lista definicji to <dl>, termin <dt>, opis <dd> - trzy pary, jedna pod drugą. Klucz sprawdza terminy w tej kolejności: Smok czerwony, Smok zielony, Smok niebieski. Opisy kopiujemy z opis.txt (Ctrl+C / Ctrl+V), nie przepisujemy - literówki w kopiowanym tekście to zbędne ryzyko.

    Typowe błędy

    Lista wypunktowana <ul> z pogrubioną nazwą wygląda podobnie, ale kryterium R.2.7 wymaga znaczników <dl>, <dt>, <dd>.

    smoki.php PHP zmienione: 8 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  26. Krok 26: Sekcja 3 z nagłówkiem

    Kryteria: R.2.4, R.2.5 ok. 1 min

    Arkusz: Sekcja 3: nagłówek trzeciego stopnia o treści „Galeria”.

    <section id="section3"> z <h3>. W bloku głównym są teraz trzy sekcje - komplet z kryterium R.2.4.

    smoki.php PHP zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  27. Krok 27: Obraz smok1.jpg

    Kryteria: R.2.6 ok. 1 min

    Arkusz: Obraz smok1.jpg z tekstem alternatywnym „Smok czerwony”.

    <img src="smok1.jpg" alt="Smok czerwony"> - to plik przeskalowany wcześniej do 300 px wysokości, leżący w tym samym folderze co smoki.php. Tekst alternatywny przepisujemy dokładnie: czyta go czytnik ekranu i pokazuje przeglądarka, gdy obraz się nie wczyta.

    Typowe błędy

    src="C:\Users\...\smok1.jpg" działa tylko na komputerze autora - na płycie egzaminatora obraz się nie wczyta. Ścieżka ma być względna.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  28. Krok 28: Obraz smok2.jpg

    Kryteria: R.2.6 ok. 1 min

    Arkusz: Obraz smok2.jpg z tekstem alternatywnym „Smok wielki”.

    Drugi obraz, ten sam wzorzec: src z nazwą pliku z archiwum, alt dokładnie z treści zadania.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  29. Krok 29: Obraz smok3.jpg

    Kryteria: R.2.6 ok. 1 min

    Arkusz: Obraz smok3.jpg z tekstem alternatywnym „Skrzydlaty łaciaty”.

    Trzeci obraz. W alt są polskie znaki - działają dzięki <meta charset="UTF-8"> z początku pliku.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  30. Krok 30: Stopka z numerem zdającego

    Kryteria: R.2.5 ok. 1 min

    Arkusz: Zawartość stopki: paragraf o treści „Stronę opracował: ”, dalej wstawiony numer zdającego.

    Paragraf <p> w <footer>. W tym rozwiązaniu po dwukropku stoi nazwisko autora - na egzaminie wpisujesz w to miejsce swój numer zdającego (PESEL), bo tego sprawdza klucz. Struktura HTML strony jest kompletna - dalej style.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  31. Krok 31: Plik styl.css: domyślne wyrównanie i krój

    Kryteria: R.4.1 ok. 2 min

    Arkusz: Domyślnie dla wszystkich selektorów: wyrównanie tekstu do środka, krój czcionki Georgia.

    Tworzymy plik styl.css obok smoki.php. „Dla wszystkich selektorów” to selektor uniwersalny * - reguła obejmuje każdy element strony. text-align: center wyśrodkowuje tekst, font-family: Georgia ustawia krój. W podglądzie od razu widać wyśrodkowanie i szeryfową czcionkę - to znak, że <link> z HTML zadziałał.

    Typowe błędy

    body { ... } też dziedziczy na całą stronę, ale klucz R.4.1 wymienia selektor * wprost.

    styl.css CSS nowy plik
    * {
        text-align: center;
        font-family: Georgia;
    }
    Podgląd strony po tym kroku (smoki.php)
  32. Krok 32: Nagłówek i stopka: tło, kolor tekstu, margines wewnętrzny

    Kryteria: R.4.2, R.4.3, R.4.6 ok. 2 min

    Arkusz: Wspólne dla bloku nagłówkowego i stopki: kolor tła Tomato, kolor czcionki MistyRose, marginesy wewnętrzne 10 px.

    Wspólne cechy dwóch elementów piszemy raz - selektory rozdzielone przecinkiem header, footer. Kolory nazwane (Tomato, MistyRose) przepisujemy z arkusza. Margines wewnętrzny to padding; zewnętrzny byłby margin - arkusz rozróżnia te dwa słowa i klucz też.

    Typowe błędy

    margin: 10px zamiast padding: 10px - odstęp będzie na zewnątrz pomarańczowego pola, a nie w nim. Kryterium R.4.6 mówi o marginesach wewnętrznych.

    styl.css CSS zmienione: 5 linii
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    Podgląd strony po tym kroku (smoki.php)
  33. Krok 33: Blok nawigacyjny: szerokość 20%

    Kryteria: R.4.4 ok. 1 min

    Arkusz: Dla bloku nawigacyjnego: szerokość 20%.

    Selektor nav (znacznik semantyczny z HTML). Szerokość w procentach liczy się względem rodzica, czyli <body> - nawigacja zajmie jedną piątą szerokości okna. Blok główny dostanie pozostałe 80%, a obok siebie ustawimy je za chwilę.

    styl.css CSS zmienione: 3 linie
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    nav {
        width: 20%;
    }
    Podgląd strony po tym kroku (smoki.php)
  34. Krok 34: Bloki 1, 2, 3: tło, wysokość, rozmiar czcionki

    Kryteria: R.4.2, R.4.4, R.4.7 ok. 2 min

    Arkusz: Dla bloku 1, bloku 2, bloku 3: kolor tła #FFAEA5, wysokość 170 px, rozmiar czcionki 200%.

    Trzy bloki mają w HTML wspólną klasę block, więc jedna reguła .block (kropka = selektor klasy) załatwia wszystkie. Trzy razy 170px daje 510px - dokładnie tyle, ile za chwilę dostanie blok główny, dzięki czemu kolumny będą równej wysokości jak na ilustracji 2. font-size: 200% to dwa razy większy tekst niż odziedziczony.

    Typowe błędy

    #block1, #block2, #block3 { ... } też jest poprawne, ale przy klasie mniej pisania i mniej miejsc na literówkę. Kolor szesnastkowy zaczyna się od #.

    styl.css CSS zmienione: 5 linii
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    nav {
        width: 20%;
    }
    .block {
        background-color: #FFAEA5;
        height: 170px;
        font-size: 200%;
    }
    Podgląd strony po tym kroku (smoki.php)
  35. Krok 35: Tylko blok 1: tło MistyRose

    Kryteria: R.4.2 ok. 1 min

    Arkusz: Jedynie dla bloku 1: kolor tła MistyRose.

    Selektor identyfikatora #block1 (krzyżyk = id). Ta reguła stoi po regule .block i jest bardziej szczegółowa (id wygrywa z klasą), więc nadpisuje tło tylko dla bloku 1. Na starcie „Baza” jest jasna, jak aktywna zakładka - to stan początkowy, do którego JavaScript będzie wracał.

    styl.css CSS zmienione: 3 linie
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    nav {
        width: 20%;
    }
    .block {
        background-color: #FFAEA5;
        height: 170px;
        font-size: 200%;
    }
    #block1 {
        background-color: MistyRose;
    }
    Podgląd strony po tym kroku (smoki.php)
  36. Krok 36: Blok główny: tło, wymiary, paski przewijania

    Kryteria: R.4.2, R.4.4, R.4.5 ok. 2 min

    Arkusz: Dla bloku głównego: kolor tła MistyRose, szerokość 80%, wysokość 510 px, paski przewijania widoczne tylko w przypadku przepełnienia zawartością.

    Selektor main. „Paski przewijania tylko przy przepełnieniu” to overflow: auto - scroll pokazywałby je zawsze, hidden obcinałby treść bez możliwości przewinięcia. Wysokość 510px równa się sumie trzech bloków nawigacji.

    Typowe błędy

    overflow: scroll daje paski zawsze, także przy pustej sekcji - klucz R.4.5 wymaga auto.

    styl.css CSS zmienione: 6 linii
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    nav {
        width: 20%;
    }
    .block {
        background-color: #FFAEA5;
        height: 170px;
        font-size: 200%;
    }
    #block1 {
        background-color: MistyRose;
    }
    main {
        background-color: MistyRose;
        width: 80%;
        height: 510px;
        overflow: auto;
    }
    Podgląd strony po tym kroku (smoki.php)
  37. Krok 37: Układ bloków: nawigacja obok bloku głównego

    Kryteria: R.3.1 ok. 3 min

    Arkusz: Podział strony na bloki zrealizowany za pomocą semantycznych znaczników bloków języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków na stronie był zgodny z ilustracją 3.

    Domyślnie każdy blok zajmuje całą szerokość i staje pod poprzednim. float: left dla nav i main ustawia je obok siebie (20% + 80% = 100%, więc mieszczą się w jednej linii). Stopka dostaje clear: both, żeby wróciła pod obie kolumny, a nie wcisnęła się obok nich. To jedno z dopuszczalnych rozwiązań - klucz przyjmuje też display: flex albo grid.

    Reguły float dopisujemy do istniejących selektorów nav i main, a footer dostaje własną regułę (wspólna z header zostaje bez zmian).

    Typowe błędy

    Bez clear: both stopka może wjechać pod pływające kolumny albo obok nich - układ przestaje zgadzać się z ilustracją 3 i R.3.1 przepada.

    styl.css CSS zmienione: 5 linii
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    nav {
        width: 20%;
        float: left;
    }
    .block {
        background-color: #FFAEA5;
        height: 170px;
        font-size: 200%;
    }
    #block1 {
        background-color: MistyRose;
    }
    main {
        background-color: MistyRose;
        width: 80%;
        height: 510px;
        overflow: auto;
        float: left;
    }
    footer {
        clear: both;
    }
    Podgląd strony po tym kroku (smoki.php)
  38. Krok 38: Sekcje 2 i 3 ukryte na starcie

    Kryteria: R.4.8 ok. 1 min

    Arkusz: Jedynie dla sekcji 2 i sekcji 3: sekcje są usunięte z DOM (patrz tabela 3).

    Tabela 3 arkusza: display: none - element jest całkowicie usunięty z układu strony (nie zajmuje miejsca, w odróżnieniu od visibility: hidden). Po tym kroku widać tylko sekcję 1, jak na ilustracji 2. Pozostałe sekcje pokaże JavaScript, zmieniając display na block.

    styl.css CSS zmienione: 3 linie
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    nav {
        width: 20%;
        float: left;
    }
    .block {
        background-color: #FFAEA5;
        height: 170px;
        font-size: 200%;
    }
    #block1 {
        background-color: MistyRose;
    }
    main {
        background-color: MistyRose;
        width: 80%;
        height: 510px;
        overflow: auto;
        float: left;
    }
    footer {
        clear: both;
    }
    #section2, #section3 {
        display: none;
    }
    Podgląd strony po tym kroku (smoki.php)
  39. Krok 39: Tabela: wyśrodkowanie, szerokość, obramowanie

    Kryteria: R.4.4, R.4.6, R.4.9 ok. 2 min

    Arkusz: Dla selektora tabeli: marginesy zewnętrzne automatycznie wyliczane przez przeglądarkę, szerokość 60%, obramowanie linią kreskowaną o szerokości 1 px i kolorze Indigo.

    Arkusz mówi wprost: selektor znacznika table, nie klasa ani id (uwaga pod listą cech CSS). margin: auto przy ustalonej szerokości wyśrodkowuje tabelę w bloku głównym. Skrót border: 1px dashed Indigo łączy grubość, styl (kreskowana) i kolor.

    Typowe błędy

    Styl tabeli przez klasę (.tabela) nie spełnia wymagania, nawet gdy wygląda identycznie - arkusz uzasadnia to „projektem późniejszej rozbudowy witryny”.

    styl.css CSS zmienione: 5 linii
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    nav {
        width: 20%;
        float: left;
    }
    .block {
        background-color: #FFAEA5;
        height: 170px;
        font-size: 200%;
    }
    #block1 {
        background-color: MistyRose;
    }
    main {
        background-color: MistyRose;
        width: 80%;
        height: 510px;
        overflow: auto;
        float: left;
    }
    footer {
        clear: both;
    }
    #section2, #section3 {
        display: none;
    }
    table {
        margin: auto;
        width: 60%;
        border: 1px dashed Indigo;
    }
    Podgląd strony po tym kroku (smoki.php)
  40. Krok 40: Lista rozwijana i przycisk: margines zewnętrzny

    Kryteria: R.4.6 ok. 1 min

    Arkusz: Dla listy rozwijanej i przycisku: marginesy zewnętrzne 20 px.

    Selektory select, button z margin: 20px - odstęp na zewnątrz elementów, więc lista i przycisk odsuwają się od siebie i od nagłówka. Tu arkusz mówi o marginesach zewnętrznych, więc margin, nie padding.

    styl.css CSS zmienione: 3 linie
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    nav {
        width: 20%;
        float: left;
    }
    .block {
        background-color: #FFAEA5;
        height: 170px;
        font-size: 200%;
    }
    #block1 {
        background-color: MistyRose;
    }
    main {
        background-color: MistyRose;
        width: 80%;
        height: 510px;
        overflow: auto;
        float: left;
    }
    footer {
        clear: both;
    }
    #section2, #section3 {
        display: none;
    }
    table {
        margin: auto;
        width: 60%;
        border: 1px dashed Indigo;
    }
    select, button {
        margin: 20px;
    }
    Podgląd strony po tym kroku (smoki.php)
  41. Krok 41: Termin listy definicji: pogrubienie i kursywa

    Kryteria: R.4.7 ok. 1 min

    Arkusz: Dla selektora terminu w liście definicji (dt): czcionka pogrubiona i pochylona.

    Znowu selektor znacznika - dt. Pogrubienie to font-weight: bold, pochylenie font-style: italic. Efekt widać po kliknięciu „Opisy”, gdy zadziała skrypt; na razie sekcja 2 jest ukryta.

    styl.css CSS zmienione: 4 linie
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    nav {
        width: 20%;
        float: left;
    }
    .block {
        background-color: #FFAEA5;
        height: 170px;
        font-size: 200%;
    }
    #block1 {
        background-color: MistyRose;
    }
    main {
        background-color: MistyRose;
        width: 80%;
        height: 510px;
        overflow: auto;
        float: left;
    }
    footer {
        clear: both;
    }
    #section2, #section3 {
        display: none;
    }
    table {
        margin: auto;
        width: 60%;
        border: 1px dashed Indigo;
    }
    select, button {
        margin: 20px;
    }
    dt {
        font-weight: bold;
        font-style: italic;
    }
    Podgląd strony po tym kroku (smoki.php)
  42. Krok 42: Termin pod kursorem: większa czcionka

    Kryteria: R.4.10 ok. 1 min

    Arkusz: W momencie gdy kursor znajdzie się na terminie w liście definicji jego rozmiar czcionki zmienia się na 180%.

    Pseudoklasa :hover opisuje stan „kursor nad elementem”. dt:hover { font-size: 180% } powiększa nazwę smoka, gdy na nią najedziesz - dokładnie to pokazuje ilustracja 5 („Smok zielony” większy od pozostałych). Arkusz stylów jest kompletny.

    styl.css CSS zmienione: 3 linie
    * {
        text-align: center;
        font-family: Georgia;
    }
    header, footer {
        background-color: Tomato;
        color: MistyRose;
        padding: 10px;
    }
    nav {
        width: 20%;
        float: left;
    }
    .block {
        background-color: #FFAEA5;
        height: 170px;
        font-size: 200%;
    }
    #block1 {
        background-color: MistyRose;
    }
    main {
        background-color: MistyRose;
        width: 80%;
        height: 510px;
        overflow: auto;
        float: left;
    }
    footer {
        clear: both;
    }
    #section2, #section3 {
        display: none;
    }
    table {
        margin: auto;
        width: 60%;
        border: 1px dashed Indigo;
    }
    select, button {
        margin: 20px;
    }
    dt {
        font-weight: bold;
        font-style: italic;
    }
    dt:hover {
        font-size: 180%;
    }
    Podgląd strony po tym kroku (smoki.php)
  43. Krok 43: Plik script.js i funkcja wywoływana kliknięciem

    Kryteria: R.3.5, R.5.6, R.5.10 ok. 3 min

    Arkusz: Skrypt jest napisany w języku JavaScript. Składa się z jednej lub trzech funkcji wywoływanych po kliknięciu na jednym z bloków w bloku nawigacyjnym.

    Tworzymy plik script.js i podpinamy go w smoki.php na końcu <body> przez <script src="script.js"></script> - na końcu, żeby wszystkie bloki i sekcje już istniały, gdy skrypt zacznie działać.

    Piszemy jedną funkcję showSection(number) - angielska nazwa mówi, co robi (wymaganie o znaczącym nazewnictwie w języku polskim lub angielskim), a parametr number powie jej, który blok kliknięto. Blok 1 dostaje onclick="showSection(1)" - to spełnia wymaganie z sekcji HTML „gdy zostanie kliknięty, jest wywoływana funkcja”. Ciało funkcji wypełnimy w kolejnych krokach.

    Typowe błędy

    Skrypt podpięty w <head> wykona się, zanim powstaną elementy block1…section3 - getElementById zwróci null i kliknięcie skończy się błędem w konsoli.

    script.js JavaScript nowy plik
    function showSection(number) {
    }
    smoki.php PHP zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  44. Krok 44: Kliknięcie: wszystkie bloki dostają tło #FFAEA5

    Kryteria: R.5.6 ok. 3 min

    Arkusz: Gdy zostanie kliknięty Blok 1: kolor tła bloku 1 zmienia się na MistyRose, pozostałe na #FFAEA5.

    Zaczynamy od „pozostałych”: najprościej jest najpierw ustawić ciemniejsze tło wszystkim trzem blokom, a dopiero potem rozjaśnić kliknięty. Wtedy nie trzeba pamiętać, który blok był aktywny wcześniej.

    Co robi ta pętla, linia po linii:

    • for (let i = 1; i <= 3; i++) - zmienna i przyjmuje kolejno 1, 2, 3.
    • 'block' + i skleja napis z liczbą: block1, block2, block3 - dokładnie identyfikatory z HTML.
    • document.getElementById(...) (tabela 2 arkusza) znajduje element o tym identyfikatorze.
    • .style.backgroundColor = '#FFAEA5' zmienia jego styl. Nazwa CSS background-color w JavaScript traci myślnik i dostaje wielką literę: backgroundColor.

    Kliknięcie „Baza” w podglądzie przyciemni na razie także blok 1 - poprawimy to w następnej linii.

    Typowe błędy

    style.background-color to błąd składni JavaScript (minus jest odejmowaniem). Nazwy z myślnikiem piszemy w notacji wielbłądziej: backgroundColor.

    script.js JavaScript zmienione: 3 linie
    function showSection(number) {
        for (let i = 1; i <= 3; i++) {
            document.getElementById('block' + i).style.backgroundColor = '#FFAEA5';
        }
    }
    Podgląd strony po tym kroku (smoki.php)
  45. Krok 45: Kliknięcie: kliknięty blok dostaje tło MistyRose

    Kryteria: R.5.7 ok. 2 min

    Arkusz: Kolor tła bloku 1 zmienia się na MistyRose.

    Jedna linia po pętli: 'block' + number to identyfikator klikniętego bloku (dla showSection(1) - block1), a jemu ustawiamy MistyRose. Kolejność ma znaczenie - gdyby ta linia stała przed pętlą, pętla zaraz by ją nadpisała i wszystkie bloki byłyby ciemne.

    W podglądzie kliknij „Baza” - blok zostaje jasny, tak jak na starcie. Kolory działają; teraz sekcje.

    script.js JavaScript zmienione: 1 linia
    function showSection(number) {
        for (let i = 1; i <= 3; i++) {
            document.getElementById('block' + i).style.backgroundColor = '#FFAEA5';
        }
        document.getElementById('block' + number).style.backgroundColor = 'MistyRose';
    }
    Podgląd strony po tym kroku (smoki.php)
  46. Krok 46: Kliknięcie: wszystkie sekcje ukryte

    Kryteria: R.5.6 ok. 2 min

    Arkusz: Sposób wyświetlania Sekcji 1 zmienia się na blokowy, pozostałe są usunięte.

    Ten sam schemat co przy kolorach, więc dopisujemy drugą linię do tej samej pętli: 'section' + i daje section1…section3, a style.display = 'none' usuwa sekcję z układu strony (wartość „usunięte” z tabeli 3 arkusza). Po tej linii kliknięcie chowa wszystkie trzy sekcje - blok główny robi się pusty. Pokażemy właściwą w następnym kroku.

    script.js JavaScript zmienione: 1 linia
    function showSection(number) {
        for (let i = 1; i <= 3; i++) {
            document.getElementById('block' + i).style.backgroundColor = '#FFAEA5';
            document.getElementById('section' + i).style.display = 'none';
        }
        document.getElementById('block' + number).style.backgroundColor = 'MistyRose';
    }
    Podgląd strony po tym kroku (smoki.php)
  47. Krok 47: Kliknięcie: widoczna sekcja klikniętego bloku

    Kryteria: R.5.8 ok. 2 min

    Arkusz: Sposób wyświetlania Sekcji 1 zmienia się na blokowy.

    Po pętli, obok linii z MistyRose, dopisujemy 'section' + number z style.display = 'block' - sekcja o numerze klikniętego bloku wraca jako element blokowy. Numeracja section1…section3 odpowiada block1…block3, więc jeden parametr number wystarcza na wszystko.

    Podgląd działa - kliknij w nim „Baza”: nic się nie zmienia, bo to stan początkowy. Pozostałe bloki podłączymy w dwóch następnych krokach.

    script.js JavaScript zmienione: 1 linia
    function showSection(number) {
        for (let i = 1; i <= 3; i++) {
            document.getElementById('block' + i).style.backgroundColor = '#FFAEA5';
            document.getElementById('section' + i).style.display = 'none';
        }
        document.getElementById('block' + number).style.backgroundColor = 'MistyRose';
        document.getElementById('section' + number).style.display = 'block';
    }
    Podgląd strony po tym kroku (smoki.php)
  48. Krok 48: Blok 2 wywołuje funkcję

    Kryteria: R.5.7, R.5.8 ok. 1 min

    Arkusz: Gdy zostanie kliknięty Blok 2: kolor tła bloku 2 zmienia się na MistyRose, pozostałe na #FFAEA5. Sposób wyświetlania Sekcji 2 zmienia się na blokowy, pozostałe są usunięte.

    Funkcja jest już gotowa na każdy numer - wystarczy w HTML dopisać blokowi 2 onclick="showSection(2)". Kliknij „Opisy” w podglądzie: blok 2 jaśnieje, blok 1 ciemnieje, w bloku głównym pojawia się lista definicji ze stylami dt (ilustracja 5).

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  49. Krok 49: Blok 3 wywołuje funkcję

    Kryteria: R.3.5, R.5.7, R.5.8, R.5.9 ok. 1 min

    Arkusz: Gdy zostanie kliknięty Blok 3: kolor tła bloku 3 zmienia się na MistyRose, pozostałe na #FFAEA5. Sposób wyświetlania Sekcji 3 zmienia się na blokowy, pozostałe są usunięte.

    onclick="showSection(3)" dla bloku 3. Sprawdź w podglądzie pełną sekwencję z klucza (R.5.9): kliknij „Galeria”, potem „Opisy”, a na koniec „Baza” - strona ma wrócić do stanu początkowego: jasny blok 1 i widoczna sekcja 1. Nasza funkcja to gwarantuje, bo za każdym razem najpierw „zeruje” wszystkie bloki i sekcje.

    Typowe błędy

    Trzy osobne funkcje, z których każda tylko pokazuje swoją sekcję i nie chowa pozostałych, po serii kliknięć zostawią widoczne wszystkie sekcje naraz - R.5.8 i R.5.9 przepadają.

    smoki.php PHP zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  50. Krok 50: Połączenie z bazą danych

    Kryteria: R.5.1, R.5.10 ok. 3 min

    Arkusz: Skrypty 1 i 2 są napisane w języku PHP. Łączą się z serwerem bazodanowym na localhost, użytkownik root bez hasła, baza danych o nazwie smoki.

    Kod PHP piszemy między <?php a ?> - serwer wykonuje go, zanim strona trafi do przeglądarki. Połączenie otwieramy raz, na samym początku pliku, i trzymamy w zmiennej $connection (znacząca, angielska nazwa - jak w całym rozwiązaniu), z której skorzystają oba skrypty. mysqli_connect z tabeli 1 arkusza przyjmuje kolejno: serwer, użytkownika, hasło (puste) i nazwę bazy.

    Od tego kroku podgląd to wynik działania strony po stronie serwera (PHP nie wykonuje się w przeglądarce) - na razie wygląda tak samo jak wcześniej, bo skrypt niczego jeszcze nie wypisuje.

    Typowe błędy

    Kolejność argumentów ma znaczenie: mysqli_connect('localhost', 'root', 'smoki') podaje „smoki” jako HASŁO. Nazwa bazy jest czwarta. Plik sprawdzaj przez http://localhost/…, nie otwierając go z dysku - inaczej PHP się nie wykona.

    smoki.php PHP zmienione: 3 linie
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  51. Krok 51: Skrypt 1: zapytanie 2 do bazy

    Kryteria: R.5.2 ok. 2 min

    Arkusz: Skrypt 1: wysyła do bazy danych zapytanie 2.

    Skrypt 1 piszemy wewnątrz <select>, bo tam mają trafić opcje. mysqli_query($connection, ...) wysyła zapytanie i zwraca wynik, który zapisujemy w zmiennej $countries. Treść zapytania to dokładnie zapytanie 2 z pliku kwerendy.txt - kraje bez powtórzeń, posortowane.

    smoki.php PHP zmienione: 3 linie
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
    <?php
    $countries = mysqli_query($connection, 'SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;');
    ?>
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 50.

  52. Krok 52: Skrypt 1: pętla po wierszach wyniku

    Kryteria: R.5.4 ok. 2 min

    Arkusz: Wszystkie zwrócone zapytaniem wiersze są zapisywane jako opcje listy rozwijanej, zgodnie z ilustracją 4.

    „Wszystkie wiersze” to pętla. mysqli_fetch_row($countries) (tabela 1 arkusza) oddaje kolejny wiersz wyniku jako tablicę numerowaną od zera, a gdy wierszy zabraknie - false. Zapis while ($row = mysqli_fetch_row($countries)) robi dwie rzeczy naraz: przypisuje wiersz do $row i sprawdza, czy coś przyszło. Pętla wykona się więc dokładnie tyle razy, ile jest krajów - pięć - i sama się zakończy.

    Ciało pętli jest jeszcze puste, więc w podglądzie lista nadal nie ma opcji.

    Typowe błędy

    Pojedyncze = w warunku while jest tu celowe (przypisanie); == porównałoby zmienną z wynikiem i pętla nie zadziałałaby poprawnie.

    smoki.php PHP zmienione: 2 linie
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
    <?php
    $countries = mysqli_query($connection, 'SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;');
    while ($row = mysqli_fetch_row($countries)) {
    }
    ?>
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 50.

  53. Krok 53: Skrypt 1: kraj jako opcja listy

    Kryteria: R.5.4 ok. 2 min

    Arkusz: Wszystkie zwrócone zapytaniem wiersze są zapisywane jako opcje listy rozwijanej, zgodnie z ilustracją 4.

    W ciele pętli echo wypisuje gotowy znacznik HTML <option> do strony. Zapytanie 2 ma jedną kolumnę, więc kraj siedzi w $row[0]. Napis jest w cudzysłowie, bo tylko wtedy PHP podstawia wartość zmiennej. Pięć obiegów pętli = pięć opcji: w podglądzie lista rozwijana ma już Bułgarię, Chiny, Francję, Japonię i Polskę - jak na ilustracji 4.

    Typowe błędy

    echo '<option>$row[0]</option>' w apostrofach wypisze dosłownie „$row[0]” pięć razy - PHP nie podstawia zmiennych w apostrofach.

    smoki.php PHP zmienione: 1 linia
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
    <?php
    $countries = mysqli_query($connection, 'SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;');
    while ($row = mysqli_fetch_row($countries)) {
        echo "<option>$row[0]</option>";
    }
    ?>
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  54. Krok 54: Skrypt 2: tylko po wysłaniu formularza

    Kryteria: R.5.3 ok. 2 min

    Arkusz: Skrypt 2, wykonywany tylko, gdy formularz wysłał dane.

    Skrypt 2 piszemy w <table>, pod wierszem nagłówkowym. Warunek isset($_POST['country']) (funkcja z tabeli 1) jest prawdziwy tylko wtedy, gdy formularz został wysłany metodą POST i zawierał pole country - przy pierwszym wejściu na stronę tablica $_POST jest pusta i cały blok if jest pomijany. Dlatego tabela na starcie ma tylko nagłówek.

    Typowe błędy

    Skrypt czyta z $_POST, bo formularz ma method="post". Przy $_GET warunek nigdy nie będzie prawdziwy - nazwa tablicy musi odpowiadać metodzie formularza.

    smoki.php PHP zmienione: 4 linie
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
    <?php
    $countries = mysqli_query($connection, 'SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;');
    while ($row = mysqli_fetch_row($countries)) {
        echo "<option>$row[0]</option>";
    }
    ?>
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
    <?php
    if (isset($_POST['country'])) {
    }
    ?>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 53.

  55. Krok 55: Skrypt 2: odczyt kraju z formularza

    Kryteria: R.5.3 ok. 1 min

    Arkusz: Wysyła do bazy danych zmodyfikowane zapytanie 1, tak że w warunku umieszczony jest kraj pochodzenia wysłany z formularza.

    Wewnątrz if bierzemy wartość wysłaną z listy rozwijanej: $_POST['country'] - klucz country to dokładnie atrybut name z <select>. Zapisujemy ją do zmiennej $country o znaczącej nazwie. Podgląd bez zmian: skrypt na razie tylko czyta.

    smoki.php PHP zmienione: 1 linia
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
    <?php
    $countries = mysqli_query($connection, 'SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;');
    while ($row = mysqli_fetch_row($countries)) {
        echo "<option>$row[0]</option>";
    }
    ?>
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
    <?php
    if (isset($_POST['country'])) {
        $country = $_POST['country'];
    }
    ?>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 53.

  56. Krok 56: Skrypt 2: zapytanie 1 z krajem z formularza

    Kryteria: R.5.2 ok. 3 min

    Arkusz: Wysyła do bazy danych zmodyfikowane zapytanie 1, tak że w warunku umieszczony jest kraj pochodzenia wysłany z formularza.

    Bierzemy zapytanie 1 z kwerendy.txt i w warunku WHERE pochodzenie = ... zamiast „Polska” wstawiamy $country. Cały napis zapytania jest w cudzysłowie (PHP podstawi zmienną), a wartość w SQL musi być w cudzysłowie albo apostrofach - stąd '$country' w apostrofach, żeby nie kolidowały z zewnętrznym cudzysłowem. Wynik zapytania trafia do $dragons.

    Typowe błędy

    Wstawianie wartości z formularza prosto do zapytania wystarcza na egzaminie, ale w prawdziwej aplikacji to podatność SQL injection - tam używa się zapytań przygotowanych (mysqli_prepare).

    smoki.php PHP zmienione: 1 linia
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
    <?php
    $countries = mysqli_query($connection, 'SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;');
    while ($row = mysqli_fetch_row($countries)) {
        echo "<option>$row[0]</option>";
    }
    ?>
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
    <?php
    if (isset($_POST['country'])) {
        $country = $_POST['country'];
        $dragons = mysqli_query($connection, "SELECT nazwa, dlugosc, szerokosc FROM smok WHERE pochodzenie = '$country';");
    }
    ?>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 53.

  57. Krok 57: Skrypt 2: pętla po smokach

    Kryteria: R.5.5 ok. 1 min

    Arkusz: Każdy zwrócony zapytaniem wiersz jest zapisywany jako kolejny wiersz tabeli, zgodnie z ilustracją 4.

    Ta sama konstrukcja co w skrypcie 1: while ($row = mysqli_fetch_row($dragons)) pobiera kolejne smoki wybranego kraju, aż wynik się skończy. Tym razem każdy wiersz ma trzy pola - w kolejności z zapytania: $row[0] nazwa, $row[1] długość, $row[2] szerokość.

    smoki.php PHP zmienione: 2 linie
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
    <?php
    $countries = mysqli_query($connection, 'SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;');
    while ($row = mysqli_fetch_row($countries)) {
        echo "<option>$row[0]</option>";
    }
    ?>
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
    <?php
    if (isset($_POST['country'])) {
        $country = $_POST['country'];
        $dragons = mysqli_query($connection, "SELECT nazwa, dlugosc, szerokosc FROM smok WHERE pochodzenie = '$country';");
        while ($row = mysqli_fetch_row($dragons)) {
        }
    }
    ?>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 53.

  58. Krok 58: Skrypt 2: smok jako wiersz tabeli

    Kryteria: R.5.5 ok. 2 min

    Arkusz: Każdy zwrócony zapytaniem wiersz jest zapisywany jako kolejny wiersz tabeli, zgodnie z ilustracją 4.

    echo w pętli dokłada do tabeli jeden <tr> z trzema <td> - nazwa, długość i szerokość trafiają pod nagłówki „Nazwa”, „Długość”, „Szerokość”. Ponieważ kod stoi wewnątrz <table>, wypisane wiersze lądują dokładnie pod wierszem nagłówkowym.

    Podgląd pokazuje stan po wybraniu Francji i kliknięciu „Szukaj” (ilustracja 4): dziesięć smoków. Lista rozwijana po wysłaniu wraca do pierwszej opcji - arkusz nie wymaga zapamiętania wyboru.

    Typowe błędy

    Komórki w innej kolejności niż nagłówki (np. długość pod „Nazwa”) to strata R.5.5 - klucz sprawdza, że komórki są „wypełnione zgodnie z nagłówkami”.

    smoki.php PHP zmienione: 1 linia
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
    <?php
    $countries = mysqli_query($connection, 'SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;');
    while ($row = mysqli_fetch_row($countries)) {
        echo "<option>$row[0]</option>";
    }
    ?>
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
    <?php
    if (isset($_POST['country'])) {
        $country = $_POST['country'];
        $dragons = mysqli_query($connection, "SELECT nazwa, dlugosc, szerokosc FROM smok WHERE pochodzenie = '$country';");
        while ($row = mysqli_fetch_row($dragons)) {
            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>";
        }
    }
    ?>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  59. Krok 59: Zamknięcie połączenia z bazą

    Kryteria: R.5.1 ok. 1 min

    Arkusz: Na końcu działania skrypt zamyka połączenie z serwerem.

    mysqli_close($connection) na końcu pliku, gdy oba skrypty już skorzystały z połączenia. Klucz sprawdza, że zamknięcie jest ostatnią operacją na bazie - dlatego nie zamykamy po skrypcie 1, bo skrypt 2 potrzebowałby połączenia ponownie. Strona smoki.php jest gotowa.

    Typowe błędy

    mysqli_close tuż za listą rozwijaną (po skrypcie 1) sprawia, że zapytanie skryptu 2 idzie po zamkniętym połączeniu - tabela zostaje pusta i przepadają R.5.1 oraz R.5.5.

    smoki.php PHP zmienione: 3 linie
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
    <?php
    $countries = mysqli_query($connection, 'SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;');
    while ($row = mysqli_fetch_row($countries)) {
        echo "<option>$row[0]</option>";
    }
    ?>
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
    <?php
    if (isset($_POST['country'])) {
        $country = $_POST['country'];
        $dragons = mysqli_query($connection, "SELECT nazwa, dlugosc, szerokosc FROM smok WHERE pochodzenie = '$country';");
        while ($row = mysqli_fetch_row($dragons)) {
            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>";
        }
    }
    ?>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    <?php
    mysqli_close($connection);
    ?>
    </body>
    </html>

    Podgląd strony bez zmian - taki jak po kroku 58.

  60. Krok 60: Wariant: HTML bez atrybutów onclick

    Kryteria: R.3.5 ok. 2 min

    Arkusz: Składa się z jednej lub trzech funkcji wywoływanych po kliknięciu na jednym z bloków w bloku nawigacyjnym.

    Rozwiązanie z onclick jest poprawne i na egzaminie wystarcza. Drugi, częściej spotykany w praktyce sposób to nasłuchiwacze zdarzeń rejestrowane w JavaScript - HTML opisuje wtedy tylko strukturę, a całe zachowanie siedzi w skrypcie. Pokazujemy go jako wariant, nie zmianę.

    Stare linie bloków zostają w komentarzu HTML <!-- … --> (przeglądarka je pomija), a pod nimi te same bloki bez atrybutu onclick. Po tym kroku kliknięcia przestają działać - podłączymy je z powrotem w skrypcie.

    Typowe błędy

    Komentarz HTML nie może zawierać -- w środku ani być zagnieżdżony - jeden <!-- i jeden --> na całą grupę linii.

    smoki.php PHP zmienione: 5 linii
    <?php
    $connection = mysqli_connect('localhost', 'root', '', 'smoki');
    ?>
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Smoki</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <header>
            <h2>Poznaj smoki!</h2>
        </header>
        <nav>
            <!-- wersja z atrybutem onclick:
            <div id="block1" class="block" onclick="showSection(1)">Baza</div>
            <div id="block2" class="block" onclick="showSection(2)">Opisy</div>
            <div id="block3" class="block" onclick="showSection(3)">Galeria</div>
            -->
            <div id="block1" class="block">Baza</div>
            <div id="block2" class="block">Opisy</div>
            <div id="block3" class="block">Galeria</div>
        </nav>
        <main>
            <section id="section1">
                <h3>Baza Smoków</h3>
                <form method="post">
                    <select name="country">
    <?php
    $countries = mysqli_query($connection, 'SELECT DISTINCT pochodzenie FROM smok ORDER BY pochodzenie;');
    while ($row = mysqli_fetch_row($countries)) {
        echo "<option>$row[0]</option>";
    }
    ?>
                    </select>
                    <button type="submit">Szukaj</button>
                </form>
                <table>
                    <tr><th>Nazwa</th><th>Długość</th><th>Szerokość</th></tr>
    <?php
    if (isset($_POST['country'])) {
        $country = $_POST['country'];
        $dragons = mysqli_query($connection, "SELECT nazwa, dlugosc, szerokosc FROM smok WHERE pochodzenie = '$country';");
        while ($row = mysqli_fetch_row($dragons)) {
            echo "<tr><td>$row[0]</td><td>$row[1]</td><td>$row[2]</td></tr>";
        }
    }
    ?>
                </table>
            </section>
            <section id="section2">
                <h3>Opisy smoków</h3>
                <dl>
                    <dt>Smok czerwony</dt>
                    <dd>Pochodzi z Chin. Ma 1000 lat. Żywi się mniejszymi zwierzętami. Posiada łuski cenne na rynkach wschodnich do wyrabiania lekarstw. Jest dziki i groźny.</dd>
                    <dt>Smok zielony</dt>
                    <dd>Pochodzi z Bułgarii. Ma 10000 lat. Żywi się mniejszymi zwierzętami, ale tylko w kolorze zielonym. Jest kosmaty. Z sierści zgubionej przez niego, tka się najdroższe materiały.</dd>
                    <dt>Smok niebieski</dt>
                    <dd>Pochodzi z Francji. Ma 100 lat. Żywi się owocami morza. Jest natchnieniem dla najlepszych malarzy. Często im pozuje. Smok ten jest przyjacielem ludzi i czasami im pomaga. Jest jednak próżny i nie lubi się przepracowywać.</dd>
                </dl>
            </section>
            <section id="section3">
                <h3>Galeria</h3>
                <img src="smok1.jpg" alt="Smok czerwony">
                <img src="smok2.jpg" alt="Smok wielki">
                <img src="smok3.jpg" alt="Skrzydlaty łaciaty">
            </section>
        </main>
        <footer>
            <p>Stronę opracował: Bartosz Bryniarski</p>
        </footer>
        <script src="script.js"></script>
    <?php
    mysqli_close($connection);
    ?>
    </body>
    </html>
    Podgląd strony po tym kroku (smoki.php)
  61. Krok 61: Nasłuchiwacz kliknięcia dla bloku 1

    Kryteria: R.3.5, R.5.6 ok. 3 min

    Arkusz: Blok 1 z treścią „Baza”, gdy zostanie kliknięty jest wywoływana funkcja JavaScript.

    addEventListener('click', ...) mówi przeglądarce: „gdy ten element zostanie kliknięty, uruchom podaną funkcję”. Pierwszy argument to nazwa zdarzenia (click, bez „on”), drugi - funkcja do wykonania. Podajemy funkcję anonimową function () { showSection(1); }, bo showSection potrzebuje argumentu, a nasłuchiwacz wywołuje funkcję bez argumentów.

    Kod stoi poza showSection, na końcu pliku - wykona się raz, przy wczytaniu skryptu, a skrypt jest podpięty na końcu <body>, więc block1 już istnieje. W podglądzie działa znów tylko „Baza”.

    Typowe błędy

    addEventListener('click', showSection(1)) wywołuje funkcję od razu przy rejestracji i jako nasłuchiwacz przekazuje jej wynik (undefined) - kliknięcie nic nie zrobi. Przekazujemy funkcję, nie jej wywołanie.

    script.js JavaScript zmienione: 4 linie
    function showSection(number) {
        for (let i = 1; i <= 3; i++) {
            document.getElementById('block' + i).style.backgroundColor = '#FFAEA5';
            document.getElementById('section' + i).style.display = 'none';
        }
        document.getElementById('block' + number).style.backgroundColor = 'MistyRose';
        document.getElementById('section' + number).style.display = 'block';
    }
    
    document.getElementById('block1').addEventListener('click', function () {
        showSection(1);
    });
    Podgląd strony po tym kroku (smoki.php)
  62. Krok 62: Nasłuchiwacze dla bloków 2 i 3

    Kryteria: R.3.5, R.5.7, R.5.8, R.5.9 ok. 2 min

    Arkusz: Blok 2 z treścią „Opisy”, gdy zostanie kliknięty jest wywoływana funkcja JavaScript. Blok 3 z treścią „Galeria”, gdy zostanie kliknięty jest wywoływana funkcja JavaScript.

    Dwa kolejne nasłuchiwacze, różnią się tylko identyfikatorem i numerem przekazywanym do showSection. Wszystkie trzy bloki znów reagują na kliknięcie - sprawdź w podglądzie sekwencję z klucza: „Galeria”, „Opisy”, „Baza”.

    Trzy prawie identyczne fragmenty to sygnał, że da się to zapisać krócej - następny krok.

    script.js JavaScript zmienione: 6 linii
    function showSection(number) {
        for (let i = 1; i <= 3; i++) {
            document.getElementById('block' + i).style.backgroundColor = '#FFAEA5';
            document.getElementById('section' + i).style.display = 'none';
        }
        document.getElementById('block' + number).style.backgroundColor = 'MistyRose';
        document.getElementById('section' + number).style.display = 'block';
    }
    
    document.getElementById('block1').addEventListener('click', function () {
        showSection(1);
    });
    document.getElementById('block2').addEventListener('click', function () {
        showSection(2);
    });
    document.getElementById('block3').addEventListener('click', function () {
        showSection(3);
    });
    Podgląd strony po tym kroku (smoki.php)
  63. Krok 63: Nasłuchiwacze w pętli

    Kryteria: R.3.5, R.5.10 ok. 3 min

    Arkusz: Należy stosować znaczące nazewnictwo zmiennych i funkcji w języku polskim lub angielskim.

    Trzy nasłuchiwacze zostają w komentarzu (// na początku każdej linii - JavaScript je pomija), a zastępuje je pętla for po numerach 1-3: identyfikator składamy jak w showSection ('block' + i), a funkcja anonimowa przekazuje i dalej.

    Ważny szczegół: let i tworzy osobną zmienną i dla każdego obiegu pętli, więc każdy nasłuchiwacz pamięta swój numer. Ze starszym var i wszystkie trzy funkcje widziałyby tę samą zmienną o końcowej wartości 4 i żaden blok nie działałby poprawnie.

    Podgląd działa jak przy onclick - a HTML jest czystszy. Oba warianty spełniają klucz; wybierz ten, który pewniej napiszesz bez błędu.

    Typowe błędy

    var i zamiast let i w tej pętli to klasyczny błąd domknięć - każde kliknięcie wywoła showSection(4), czyli getElementById zwróci null i skrypt się wysypie.

    script.js JavaScript zmienione: 16 linii
    function showSection(number) {
        for (let i = 1; i <= 3; i++) {
            document.getElementById('block' + i).style.backgroundColor = '#FFAEA5';
            document.getElementById('section' + i).style.display = 'none';
        }
        document.getElementById('block' + number).style.backgroundColor = 'MistyRose';
        document.getElementById('section' + number).style.display = 'block';
    }
    
    // wersja z trzema osobnymi nasłuchiwaczami:
    // document.getElementById('block1').addEventListener('click', function () {
    //     showSection(1);
    // });
    // document.getElementById('block2').addEventListener('click', function () {
    //     showSection(2);
    // });
    // document.getElementById('block3').addEventListener('click', function () {
    //     showSection(3);
    // });
    
    for (let i = 1; i <= 3; i++) {
        document.getElementById('block' + i).addEventListener('click', function () {
            showSection(i);
        });
    }
    Podgląd strony po tym kroku (smoki.php)
  64. Krok 64: Plik przeglądarka.txt i nagranie płyty

    ok. 5 min

    Arkusz: Po zakończeniu pracy utwórz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowana była poprawność działania witryny. Nagraj płytę z rezultatami pracy.

    W przeglądarka.txt wpisujemy nazwę przeglądarki, w której sprawdzaliśmy stronę przez http://localhost/…. Na egzaminie nazwa pliku dokładnie jak w arkuszu, z „ą” - w tym rozwiązaniu plik nazywa się przegladarka.txt tylko dlatego, że podgląd nie przyjmuje polskich znaków w nazwach plików. W folderze z numerem zdającego muszą być: import.jpg, kw1.png, kw2.png, kw3.png, kw4.png, kwerendy.txt, przeglądarka.txt, smok1.jpg, smok2.jpg, smok3.jpg, smoki.php, styl.css i script.js.

    Nagrywamy płytę, sprawdzamy jej odczyt na stanowisku i opisujemy numerem zdającego. Pusta lub nieczytelna płyta to zero punktów za wszystkie pięć rezultatów.

    przegladarka.txt Tekst nowy plik
    Google Chrome

    Podgląd strony bez zmian - taki jak po kroku 63.