Przejdź do głównej treści
INF.03-08-24.06-SGCzerwiec 2024 · 54 kroki · ok. 90 min · 43 kryteria z klucza

Rozwiązanie krok po kroku: Rejestracja użytkownika sklepu (Wersja podstawowa)

Formularz rejestracji nowego użytkownika sklepu: baza klienci (osoby, ich adresy i telefony - jedna osoba może mieć kilka adresów i kilka numerów) i cztery zapytania - warunek na datę urodzenia, DISTINCT z sortowaniem, złączenie JOIN i ALTER TABLE ... ADD COLUMN ... AFTER - potem plakietka wycięta z grafiki z przezroczystym tłem i strona rejestracja.html: blok boczny z promocjami, baner, blok główny z trzema zakładkami formularza, pasek postępu i stopka. JavaScript przełącza zakładki, wydłuża pasek postępu po opuszczeniu każdego pola i wypisuje wpisane dane w konsoli.

Kroki idą zdanie po zdaniu za treścią arkusza - przy każdym jest polecenie z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Skrypt powstaje najpierw najprościej (atrybuty onclick i onblur, getElementById, style.display), a na końcu przechodzi do wersji z prawdziwych projektów: pasek liczony z wypełnionych pól zamiast z kliknięć, nasłuchiwacze zdarzeń i zgoda RODO sprawdzana przed zatwierdzeniem.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid)” jest drugi sposób rozwiązania tego samego arkusza: bloki na siatce CSS w kolejności treści, kolory w zmiennych, zakładki przełączane klasą CSS i skrypt bez atrybutów w HTML-u - obie wersje są zgodne z kluczem.

Baza i grafika pochodzą z prawdziwego archiwum pliki8 (załącznik do arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robi się je samemu, z całego ekranu. Skrypt został sprawdzony w prawdziwej przeglądarce: przełączanie zakładek, szerokości paska po kolejnych polach i napis w konsoli. Podgląd strony jest interaktywny - zakładki i pasek postępu działają tak, jak u ucznia.

Jak liczą się punkty. Klucz ma 43 kryteria (R.1.1 - R.5.9), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 33 punkty - 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.

  1. Etap 1: Baza danych

    Kroki 1-7 · po tym etapie masz 6 z 43 kryteriów (pkt)

    Krok 1: Baza danych klienci

    ok. 2 min
    Polecenie z arkusza

    Utwórz bazę danych o nazwie klienci, z zestawem polskich znaków (np. utf8_unicode_ci)

    Najpierw archiwum pliki8.zip z pulpitu (hasło _Rejestr@cja_ - podkreślenia na obu końcach i małpa zamiast „a”) rozpakowuje się do folderu nazwanego numerem zdającego. W phpMyAdmin: Nowa, nazwa klienci, porównywanie utf8_unicode_ci.

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

    ok. 2 min
    Polecenie z arkusza

    Do bazy zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum

    Zaznaczona baza klienci, potem Import → baza.sql → Wykonaj. Powstają trzy tabele z obrazu 1: osoby (7 osób z datą urodzenia dataUr), adresy i telefony - obie z polem Osoby_id, które wskazuje właściciela. Jedna osoba może mieć kilka adresów i kilka telefonów, dlatego są to osobne tabele.

  3. Krok 3: Zrzut ekranu import.png

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych klienci czynność udokumentowano plikiem o nazwie import w formacie PNG

    ok. 2 min
    Polecenie z arkusza

    Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie PNG i nazwij import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel.

    Print Screen, wklejenie do edytora grafiki i zapis jako import.png. Zrzuty zapytań idą później do JPEG.

    Typowe błędy

    Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).

  4. Krok 4: Zapytanie 1: osoby urodzone po 2000 roku

    Kryteria: ,

    R.1.2 Zapisano plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania

    R.1.3 Wykonano zapytanie 1 wybierające jedynie imiona i nazwiska osób urodzonych po 2000 roku. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko FROM osoby WHERE dataUr >="2001-01-01"; (lub dataUr > "2000-12-31") oraz wynik działania udokumentowano zrzutem, na którym są widoczne jedynie dane: Anna Kowalewska, Ewa Kowalska, Andrzej Nowak

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 1: wybierające jedynie imiona i nazwiska osób urodzonych po 2000 roku

    • SELECT imie, nazwisko - dwa pola,
    • FROM osoby,
    • WHERE dataUr > '2000-12-31' - „po 2000 roku” znaczy od 1 stycznia 2001; datę zapisuje się jako tekst w formacie RRRR-MM-DD, a baza porównuje ją jak datę. Równoważne są dataUr >= '2001-01-01' i YEAR(dataUr) > 2000 (sprawdzone - ten sam wynik).

    Wynik: Anna Kowalewska, Ewa Kowalska, Andrzej Nowak - jak w kluczu. Zapytania zapisuje się w kwerendy.txt, zrzut jako kw1.jpg.

    Typowe błędy

    dataUr > '2000' albo dataUr >= '2000-01-01' łapie też osoby urodzone w 2000 roku, a te nie są urodzone „po 2000 roku”.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT imie, nazwisko FROM osoby WHERE dataUr > '2000-12-31';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: miasta bez powtórzeń, alfabetycznie

    Kryteria:

    R.1.4 Wykonano zapytanie 2 wybierające nazwy miast, z których pochodzą klienci posortowane alfabetycznie rosnąco. Nazwy miast nie mogą się powtarzać. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT DISTINCT miasto FROM `adresy` ORDER BY miasto; oraz wynik działania udokumentowano zrzutem, na którym są widoczne dokładnie 4 rekordy w kolejności: Kraków, Poznań, Warszawa, Wrocław

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: wybierające nazwy miast, z których pochodzą klienci posortowane alfabetycznie rosnąco. Nazwy miast nie mogą się powtarzać

    • SELECT DISTINCT miasto - DISTINCT usuwa powtórzenia: Poznań i Warszawa występują w adresach po dwa razy, a w wyniku raz,
    • FROM adresy,
    • ORDER BY miasto - sortowanie rosnąco (ASC jest domyślne).

    Wynik: 4 wiersze - Kraków, Poznań, Warszawa, Wrocław, w kolejności z klucza. Zrzut: kw2.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko FROM osoby WHERE dataUr > '2000-12-31';
    
    -- Zapytanie 2
    SELECT DISTINCT miasto FROM adresy ORDER BY miasto;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: osoby z numerami telefonów

    Kryteria:

    R.1.5 Wykonano zapytanie 3 wybierające jedynie imiona i nazwiska osób oraz odpowiadające im numery telefonów. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko, telefony.numer FROM osoby JOIN telefony ON osoby.id = telefony.Osoby_id; (możliwe również INNER JOIN lub porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 9 rekordów z czego dla Anny Kowalewskiej i Anny Nowak są dwa numery telefonu

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: wybierające jedynie imiona i nazwiska osób oraz odpowiadające im numery telefonów. Należy posłużyć się relacją

    • SELECT imie, nazwisko, telefony.numer - przy numer nazwa tabeli: kolumna o tej nazwie jest też w tabeli adresy, więc dobrze ją doprecyzować,
    • FROM osoby JOIN telefony ON osoby.id = telefony.Osoby_id - relacja: do osoby dołączany jest każdy jej telefon.

    Wynik: 9 wierszy - tyle, ile telefonów; Anna Kowalewska i Anna Nowak występują dwa razy, bo mają po dwa numery (zgodnie z kluczem). Zrzut: kw3.jpg.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko FROM osoby WHERE dataUr > '2000-12-31';
    
    -- Zapytanie 2
    SELECT DISTINCT miasto FROM adresy ORDER BY miasto;
    
    -- Zapytanie 3
    SELECT imie, nazwisko, telefony.numer FROM osoby JOIN telefony ON osoby.id = telefony.Osoby_id;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: nowa kolumna numerMieszkania

    Kryteria:

    R.1.6 Wykonano zapytanie 4 dodające do tabeli adresy kolumnę numerMieszkania typu całkowitego, po kolumnie numer. W pliku z kwerendami lub na zrzucie istnieje zapis np.: ALTER TABLE adresy ADD COLUMN numerMieszkania INT AFTER numer; (dowolny typ całkowity, poprawnie również bez słowa COLUMN) oraz wynik działania udokumentowano zrzutem, na którym widoczne jest poprawnie wykonane zapytanie lub struktura tabeli z dodaną kolumną

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 4: Dodające kolumnę numerMieszkania typu całkowitego, do tabeli Adresy po kolumnie numer

    • ALTER TABLE adresy - zmiana struktury tabeli (w bazie ma nazwę małą literą, arkusz pisze „Adresy”),
    • ADD COLUMN numerMieszkania INT - nowa kolumna typu całkowitego; istniejące wiersze dostaną w niej NULL,
    • AFTER numer - miejsce kolumny: zaraz po numer, a nie na końcu tabeli.

    Na zrzucie kw4.jpg widać komunikat albo strukturę tabeli: id, Osoby_id, ulica, numer, numerMieszkania, miasto.

    Typowe błędy

    Bez AFTER numer kolumna trafia na koniec tabeli, za miasto.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko FROM osoby WHERE dataUr > '2000-12-31';
    
    -- Zapytanie 2
    SELECT DISTINCT miasto FROM adresy ORDER BY miasto;
    
    -- Zapytanie 3
    SELECT imie, nazwisko, telefony.numer FROM osoby JOIN telefony ON osoby.id = telefony.Osoby_id;
    
    -- Zapytanie 4
    ALTER TABLE adresy ADD COLUMN numerMieszkania INT AFTER numer;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

    Kroki 8-30 · po tym etapie masz 20 z 43 kryteriów (pkt)

    Krok 8: obraz.png: niebieska plakietka, przezroczyste tło, 200 px

    Kryteria:

    R.2.1 Plik obraz.png przeskalowano z zachowaniem proporcji do wysokości 200 px, jest on przezroczysty oraz widoczna jest na nim jedynie niebieska plakietka z pętelką

    ok. 5 min
    Polecenie z arkusza

    Plik obraz.jpg wypakowany z archiwum należy skadrować, tak aby była widoczna tylko niebieska plakietka z pętelką (patrz obraz 2), ustawić tło przezroczyste oraz przeskalować z zachowaniem proporcji do wysokości 200 px. Obraz zapisać pod tą samą nazwą w formacie PNG

    Trzy operacje w GIMP-ie:
    - kadr: narzędzie Kadrowanie wokół prawej plakietki. Uwaga na pętelki: do niebieskiej plakietki należy zielona nitka (zaczepiona w jej otworze), a niebieska nitka po lewej należy do zielonej plakietki - tak jest też na obrazie 2,
    - przezroczystość: Warstwa → Przezroczystość → Dodaj kanał alfa, potem Zaznaczanie rozmyte (różdżka) na białym tle i Usuń. Białe pole wewnątrz pętelki i otwór na nitkę są od tła oddzielone, więc zaznacza się je osobno (z klawiszem Shift). Białego procentu i koszyka nie wolno zaznaczyć - są częścią plakietki,
    - skala: Obraz → Skaluj obraz, łańcuch zamknięty, wysokość 200 px; szerokość wychodzi 92 px (kadr miał 286×620 px).

    Zapis przez Plik → Wyeksportuj jako obraz.png - JPEG nie ma przezroczystości. Podgląd: oryginał i gotowa plakietka na szachownicy, która pokazuje przezroczyste miejsca.

    Typowe błędy

    Zapis do JPEG - przezroczyste tło zamienia się na białe (albo czarne), a klucz wymaga przezroczystości.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: Plik rejestracja.html w HTML5

    ok. 2 min
    Polecenie z arkusza

    Składa się ze strony o nazwie rejestracja.html zapisanej w języku HTML5

    Deklaracja <!DOCTYPE html> i szkielet z sekcjami head i body. Strona bez PHP - otwiera się ją prosto z dysku.

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

    ok. 1 min
    Polecenie z arkusza

    Ustawiony język zawartości strony na polski

    Atrybut lang="pl" w znaczniku <html>.

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

    Kryteria:

    R.2.2 Witrynę internetową zapisano w pliku rejestracja.html oraz zapisano jawnie standard kodowania polskich znaków i deklarację HTML5 <!DOCTYPE HTML> i zadeklarowano język witryny polski np.<HTML lang="pl">. Strona zawiera sekcje head i body

    ok. 1 min
    Polecenie z arkusza

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

    <meta charset="UTF-8"> jako pierwszy element <head>. Z deklaracją HTML5, językiem i nazwą pliku to jedno kryterium klucza.

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

    Kryteria:

    R.2.3 Nadano tytuł stronie: Sklep - rejestracja

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Sklep - rejestracja”

    <title> w <head>.

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

    Kryteria:

    R.3.8 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css , formatowanie CSS pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy zdający źle przypisał co najmniej jeden selektor do bloku (np. kropka zamiast #)

    ok. 1 min
    Polecenie z arkusza

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

    Nazwa pliku: styl.css. Całe formatowanie ma pochodzić z tego pliku.

    Typowe błędy

    Klucz odbiera R.3.8 także wtedy, gdy choć jeden selektor nie trafia w blok (np. kropka zamiast #).

    rejestracja.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  14. Krok 14: Bloki: boczny, baner, główny, pasek postępu, stopka

    Kryteria:

    R.2.4 Układ strony zdefiniowano dzieląc ją na bloki: boczny, baner, główny, blok paska postępu oraz stopkę. Zastosowano semantyczne znaczniki sekcji HTML5 zgodnie z ich znaczeniem, w tym do części nagłówkowej - header, stopki - footer, dopuszcza się zagnieżdżenie bloków div w znacznikach semantycznych

    ok. 2 min
    Polecenie z arkusza

    Podział strony na blok boczny i obok niego bloki: baner, główny, blok paska postępu oraz na dole blok stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML 5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2

    Blok boczny z promocjami to treść poboczna wobec formularza - znacznik <aside>. Baner to <header>, blok główny <main>, pasek postępu - <section> z identyfikatorem progress, stopka - <footer> (klucz R.2.4 wymaga wprost header i footer). Kolejność w kodzie odpowiada kolejności czytania: najpierw blok boczny, potem kolumna z banerem, formularzem i paskiem.

    rejestracja.html HTML zmienione: 10 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
        </aside>
        <header>
        </header>
        <main>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  15. Krok 15: Blok boczny: plakietka

    Kryteria:

    R.2.6 W bloku bocznym umieszczono obraz o nazwie "obraz" w formacie PNG lub JPEG z tekstem alternatywnym "promocje"

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku bocznego: Obraz o nazwie obraz.png z tekstem alternatywnym „promocje”

    Obraz z przezroczystym tłem - na niebieskim bloku plakietka nie ma białego prostokąta wokół.

    rejestracja.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
        </aside>
        <header>
        </header>
        <main>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  16. Krok 16: Blok boczny: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Nagłówek drugiego stopnia o treści „Sprawdź promocje”

    <h2> pod obrazem.

    rejestracja.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
        </aside>
        <header>
        </header>
        <main>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  17. Krok 17: Blok boczny: tabela promocji

    Kryteria:

    R.2.7 W bloku bocznym umieszczono tabelę zgodną z Obrazem 3 arkusza egzaminacyjnego, której pierwszy wiersz ma komórki nagłówkowe, zastosowano znaczniki <table>, <tr>, <th>, <td>

    ok. 2 min
    Polecenie z arkusza

    Tabela, której pierwszy wiersz jest złożony z komórek nagłówkowych, wypełniona treściami widocznymi na obrazie 3

    Pierwszy wiersz z komórkami nagłówkowymi <th> („co?”, „ile taniej?”), potem dwa wiersze z komórkami <td> - treść przepisana z obrazu 3.

    rejestracja.html HTML zmienione: 14 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
        </header>
        <main>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  18. Krok 18: Baner: nagłówek

    ok. 1 min
    Polecenie z arkusza

    Zawartość banera: Nagłówek pierwszego stopnia o treści „Zarejestruj się w sklepie”

    <h1> w banerze.

    rejestracja.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  19. Krok 19: Blok główny: trzy przyciski zakładek

    Kryteria:

    R.2.8 W bloku głównym umieszczono trzy przyciski o treściach „Klient”, „Adres”, „Kontakt”

    ok. 1 min
    Polecenie z arkusza

    Zawartość bloku głównego: Trzy przyciski o treściach: „Klient”, „Adres”, „Kontakt”, wciśnięcie dowolnego z nich wywołuje funkcję aktywującą kolejno blok pierwszy, drugi, trzeci

    Trzy <button> jeden po drugim - wyglądają jak zakładki nad formularzem. Funkcję, którą wywołają, przycisk dostanie w części o JavaScripcie. Przyciski nie stoją w znaczniku <form>, więc nie wysyłają żadnego formularza i nie przeładowują strony.

    rejestracja.html HTML zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  20. Krok 20: Blok 1: imię z podpowiedzią

    ok. 2 min
    Polecenie z arkusza

    Blok pierwszy z kontrolkami: Paragraf „Imię”, następnie pole edycyjne z podpowiedzią „Wpisz dane...”

    Każda zakładka to <div> z klasą tab (wspólny wygląd) i identyfikatorem - client, address, contact - po którym skrypt pokaże albo ukryje blok. Podpis pola to akapit <p>, jak każe arkusz; podpowiedź - atrybut placeholder. Identyfikator pola (firstName) posłuży funkcji zatwierdzającej.

    rejestracja.html HTML zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
            </div>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  21. Krok 21: Blok 1: nazwisko

    ok. 1 min
    Polecenie z arkusza

    Paragraf „Nazwisko”, następnie pole edycyjne

    Drugi podpis i pole tekstowe, bez podpowiedzi (arkusz jej nie wymaga).

    rejestracja.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
            </div>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  22. Krok 22: Blok 1: data urodzenia

    Kryteria:

    R.3.2 Pierwszy blok z kontrolkami ma dwa pola edycyjne oraz jedno typu date, dla pola do wpisywania imienia zdefiniowano placeholder "Wpisz dane..."

    ok. 1 min
    Polecenie z arkusza

    Paragraf „Data urodzenia”, następnie pole edycyjne typu daty

    Pole type="date" - przeglądarka pokazuje maskę dd.mm.rrrr i kalendarz (obraz 2). Wartość pola zawsze ma postać RRRR-MM-DD, niezależnie od tego, jak data wyświetla się na ekranie - widać to w konsoli na obrazie 6.

    rejestracja.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  23. Krok 23: Blok 2: ulica

    ok. 1 min
    Polecenie z arkusza

    Blok drugi z kontrolkami: Paragraf „Ulica”, następnie pole edycyjne

    Druga zakładka (id="address"). Na razie wszystkie bloki są widoczne jeden pod drugim - ukryje je arkusz stylów.

    rejestracja.html HTML zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
            </div>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  24. Krok 24: Blok 2: numer domu

    ok. 1 min
    Polecenie z arkusza

    Paragraf „Numer”, następnie pole edycyjne typu numerycznego

    Pole type="number" przyjmuje tylko liczbę i ma strzałki do zmiany wartości.

    rejestracja.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
            </div>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  25. Krok 25: Blok 2: miasto

    Kryteria:

    R.3.3 Drugi blok z kontrolkami ma dwa pola edycyjne oraz jedno typu number

    ok. 1 min
    Polecenie z arkusza

    Paragraf „Miasto”, następnie pole edycyjne

    Trzecie pole drugiej zakładki. Komplet z R.3.3: dwa pola tekstowe i jedno liczbowe.

    rejestracja.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  26. Krok 26: Blok 3: numer komórkowy

    Kryteria:

    R.2.9 W bloku głównym znajdują się trzy bloki, w każdym z nich umieszczono przynajmniej jedno pole edycyjne oraz przynajmniej jeden podpis w paragrafie

    ok. 1 min
    Polecenie z arkusza

    Blok trzeci z kontrolkami: Paragraf „Numer komórkowy”, następnie pole edycyjne typu numeru telefonu

    Trzecia zakładka (id="contact"), pole type="tel" - telefon otwiera przy nim klawiaturę numeryczną. Każdy z trzech bloków ma już pole i podpis w akapicie (R.2.9).

    rejestracja.html HTML zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone">
            </div>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  27. Krok 27: Blok 3: zgoda RODO

    Kryteria:

    R.3.4 Trzeci blok z kontrolkami ma jedno pole typu tel i jedno typu checkbox

    ok. 1 min
    Polecenie z arkusza

    Pole wyboru podpisane „Akceptuję RODO”

    Pole wyboru to type="checkbox", a podpis - <label> połączony z polem przez for/id (kliknięcie napisu też zaznacza pole). <br> przenosi pole do nowej linii, pod numer telefonu - jak na obrazie 5.

    rejestracja.html HTML zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
            </div>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  28. Krok 28: Blok 3: przycisk „Zatwierdź dane”

    Kryteria:

    R.2.10 W trzecim bloku umieszczono przycisk "Zatwierdź dane"

    ok. 1 min
    Polecenie z arkusza

    Przycisk „Zatwierdź dane”, którego kliknięcie powoduje wywołanie funkcji zatwierdzającej

    Czwarty przycisk na stronie; funkcję dostanie w części o JavaScripcie.

    rejestracja.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button>Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  29. Krok 29: Pasek postępu: pusty blok

    ok. 1 min
    Polecenie z arkusza

    Zawartość paska postępu: pusty blok (sekcja)

    W sekcji progress druga, pusta sekcja z identyfikatorem bar - to ona będzie granatowym paskiem, którego szerokość zmienia skrypt. Zewnętrzna sekcja to szare tło całego paska.

    rejestracja.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button>Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  30. Krok 30: Stopka

    Kryteria:

    R.2.5 W bloku bocznym zapisano nagłówek h2 "Sprawdź promocje" , w banerze zapisano nagłówek h1: "Zarejestruj się w sklepie" , w bloku stopki nagłówek h4: "Rejestrację do sklepu wykonał:" z numerem zdającego

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: nagłówek czwartego stopnia o treści: „Rejestrację do sklepu wykonał: ”, dalej wstawiony numer zdającego

    Tym razem nie akapit, tylko <h4>. Na egzaminie po dwukropku wpisuje się swój numer zdającego (PESEL) - tutaj stoi imię i nazwisko autora rozwiązania. Z tym krokiem są wszystkie nagłówki z R.2.5.

    rejestracja.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button>Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  31. Etap 3: Styl CSS

    Kroki 31-43 · po tym etapie masz 33 z 43 kryteriów (pkt)

    Krok 31: Plik styl.css: krój Cambria

    Kryteria:

    R.4.1 Ustawiono domyślne formatowanie wszystkich selektorów (dla *): krój czcionki Cambria

    ok. 1 min
    Polecenie z arkusza

    Domyślne formatowanie wszystkich selektorów: krój czcionki Cambria

    Selektor uniwersalny *.

    styl.css CSS nowy plik
    * {
        font-family: Cambria;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  32. Krok 32: Tło strony

    ok. 1 min
    Polecenie z arkusza

    Dla ciała dokumentu: kolor tła Linen

    „Ciało dokumentu” to body. Linen to jasny, lekko kremowy kolor - widać go między blokami.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  33. Krok 33: Blok boczny, baner i stopka: wspólne cechy

    ok. 1 min
    Polecenie z arkusza

    Wspólne dla bloków bocznego, banera i stopki: kolor tła SteelBlue, biały kolor czcionki, wyrównanie tekstu do środka

    Trzy selektory znaczników po przecinku - jedna reguła. Wyśrodkowanie dotyczy też obrazu w bloku bocznym (obraz jest elementem liniowym).

    styl.css CSS zmienione: 5 linii
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  34. Krok 34: Blok boczny: wymiary, marginesy, cień

    Kryteria:

    R.4.8 Ustawiono dla bloku bocznego: box-shadow: 4px 4px 5px DimGray

    ok. 2 min
    Polecenie z arkusza

    Dodatkowo dla bloku bocznego: szerokość 25%, wysokość 510 px, margines zewnętrzny górny i dolny 0, lewy i prawy 1%, cień bloku o przesunięciu 4 px w obu osiach, rozmyciu 5 px i kolorze DimGray

    margin: 0 1% - góra i dół 0, lewa i prawa strona po 1%. box-shadow: 4px 4px 5px DimGray: przesunięcie w poziomie, przesunięcie w pionie, rozmycie i kolor - cień pada w prawo i w dół, jak na obrazie 2.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    aside {
        width: 25%;
        height: 510px;
        margin: 0 1%;
        box-shadow: 4px 4px 5px DimGray;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  35. Krok 35: Baner: wymiary

    ok. 1 min
    Polecenie z arkusza

    Dodatkowo dla banera: szerokość 73%, wysokość 80 px

    Rachunek szerokości: blok boczny 25% + marginesy 2% + baner 73% = 100%, więc oba zmieszczą się obok siebie.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    aside {
        width: 25%;
        height: 510px;
        margin: 0 1%;
        box-shadow: 4px 4px 5px DimGray;
    }
    header {
        width: 73%;
        height: 80px;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  36. Krok 36: Blok główny: wymiary

    ok. 1 min
    Polecenie z arkusza

    Dla bloku głównego: szerokość 73%, wysokość 400 px

    Ta sama szerokość co baner - blok główny stanie pod nim.

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    aside {
        width: 25%;
        height: 510px;
        margin: 0 1%;
        box-shadow: 4px 4px 5px DimGray;
    }
    header {
        width: 73%;
        height: 80px;
    }
    main {
        width: 73%;
        height: 400px;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  37. Krok 37: Przyciski

    Kryteria: ,

    R.4.3 Ustawiono biały kolor czcionki dla bloków bocznego, banera i stopki oraz przycisków

    R.4.6 Ustawiono wyrównanie tekstu do środka dla bloków bocznego, banera i stopki oraz rozmiar czcionki 130% dla przycisków

    ok. 2 min
    Polecenie z arkusza

    Dla wszystkich przycisków: kolor tła SteelBlue, biały kolor czcionki, szerokość 20%, marginesy wewnętrzne 15 px, margines zewnętrzny górny 30 px, rozmiar czcionki 130%, bez obramowania

    Selektor button łapie cztery przyciski: trzy zakładki i „Zatwierdź dane”. Szerokość 20% liczy się od szerokości rodzica - zakładek od bloku głównego, a przycisku zatwierdzającego od jego zakładki, dlatego jest węższy (obraz 5). Ta reguła zamyka biel czcionki (R.4.3) oraz wyśrodkowanie z rozmiarem 130% (R.4.6).

    styl.css CSS zmienione: 9 linii
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    aside {
        width: 25%;
        height: 510px;
        margin: 0 1%;
        box-shadow: 4px 4px 5px DimGray;
    }
    header {
        width: 73%;
        height: 80px;
    }
    main {
        width: 73%;
        height: 400px;
    }
    button {
        background-color: SteelBlue;
        color: white;
        width: 20%;
        padding: 15px;
        margin-top: 30px;
        font-size: 130%;
        border: none;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  38. Krok 38: Przycisk pod kursorem

    Kryteria:

    R.4.10 Gdy kursor znajduje się na przycisku jego kolor tła zmienia się na Navy

    ok. 1 min
    Polecenie z arkusza

    Gdy kursor znajduje się na przycisku jego kolor tła zmienia się na Navy

    Pseudoklasa :hover - obraz 2 pokazuje kursor na zakładce „Klient”, granatowej.

    styl.css CSS zmienione: 3 linie
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    aside {
        width: 25%;
        height: 510px;
        margin: 0 1%;
        box-shadow: 4px 4px 5px DimGray;
    }
    header {
        width: 73%;
        height: 80px;
    }
    main {
        width: 73%;
        height: 400px;
    }
    button {
        background-color: SteelBlue;
        color: white;
        width: 20%;
        padding: 15px;
        margin-top: 30px;
        font-size: 130%;
        border: none;
    }
    button:hover {
        background-color: Navy;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  39. Krok 39: Bloki z kontrolkami: wygląd i widoczny tylko pierwszy

    Kryteria:

    R.5.5 W stanie początkowym jest pokazany pierwszy blok z imieniem i nazwiskiem, a pozostałe są utworzone i ukryte (w skrypcie lub CSS)

    ok. 2 min
    Polecenie z arkusza

    Dla trzech bloków z kontrolkami: kolor tła LightBlue, margines zewnętrzny prawy 80 px, marginesy wewnętrzne 10 px. W stanie początkowym jest widoczny tylko pierwszy blok z kontrolkami

    Klasa .tab - wspólne cechy trzech bloków. Drugi i trzeci blok ukrywa display: none: blok znika i nie zajmuje miejsca, więc każda zakładka pojawi się w tym samym miejscu pod przyciskami (obrazy 4 i 5). Bloki są w kodzie strony, tylko niewidoczne - skrypt będzie je pokazywał.

    styl.css CSS zmienione: 8 linii
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    aside {
        width: 25%;
        height: 510px;
        margin: 0 1%;
        box-shadow: 4px 4px 5px DimGray;
    }
    header {
        width: 73%;
        height: 80px;
    }
    main {
        width: 73%;
        height: 400px;
    }
    button {
        background-color: SteelBlue;
        color: white;
        width: 20%;
        padding: 15px;
        margin-top: 30px;
        font-size: 130%;
        border: none;
    }
    button:hover {
        background-color: Navy;
    }
    .tab {
        background-color: LightBlue;
        margin-right: 80px;
        padding: 10px;
    }
    #address, #contact {
        display: none;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  40. Krok 40: Pasek postępu: tło i szerokość

    Kryteria: ,

    R.4.2 Ustawiono kolor tła Linen dla body, SteelBlue dla bloków bocznego, banera i stopki oraz przycisków, LightGrey dla bloku paska postępu oraz LightBlue dla bloków z kontrolkami

    R.4.7 Ustawiono marginesy wewnętrzne (padding) 15px dla przycisków, 10px dla bloków z kontrolkami oraz marginesy zewnętrzne (margin) dla bloku bocznego: jedynie lewy i prawy 1%, górny 30px dla przycisków, prawy 80px dla bloków z kontrolkami i dolny 10px dla paska postępu

    ok. 1 min
    Polecenie z arkusza

    Dla bloku paska postępu: kolor tła LightGrey, szerokość 73%, margines zewnętrzny dolny 10 px

    Szare tło całego paska. Ta reguła zamyka kolory tła (R.4.2: Linen, SteelBlue, LightGrey, LightBlue) i komplet marginesów z R.4.7.

    styl.css CSS zmienione: 5 linii
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    aside {
        width: 25%;
        height: 510px;
        margin: 0 1%;
        box-shadow: 4px 4px 5px DimGray;
    }
    header {
        width: 73%;
        height: 80px;
    }
    main {
        width: 73%;
        height: 400px;
    }
    button {
        background-color: SteelBlue;
        color: white;
        width: 20%;
        padding: 15px;
        margin-top: 30px;
        font-size: 130%;
        border: none;
    }
    button:hover {
        background-color: Navy;
    }
    .tab {
        background-color: LightBlue;
        margin-right: 80px;
        padding: 10px;
    }
    #address, #contact {
        display: none;
    }
    #progress {
        background-color: LightGrey;
        width: 73%;
        margin-bottom: 10px;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  41. Krok 41: Pusty blok paska: 4% na start

    Kryteria: ,

    R.5.2 W stanie początkowym pasek postępu ma szerokość 4% (w skrypcie lub CSS)

    R.4.4 Ustawiono wysokość bloku bocznego 510px, banera 80px, głównego 400px oraz 30px dla paska postępu

    ok. 1 min
    Polecenie z arkusza

    Dla pustego bloku w bloku paska postępu: kolor tła Navy, szerokość 4%, wysokość 30 px

    Granatowy pasek o szerokości 4% szarego tła - to stan początkowy, od którego skrypt zacznie liczyć (R.5.2). Wysokość 30 px nadaje wysokość całemu paskowi, bo zewnętrzna sekcja nie ma własnej. Komplet wysokości z R.4.4: 510, 80, 400 i 30 px.

    styl.css CSS zmienione: 5 linii
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    aside {
        width: 25%;
        height: 510px;
        margin: 0 1%;
        box-shadow: 4px 4px 5px DimGray;
    }
    header {
        width: 73%;
        height: 80px;
    }
    main {
        width: 73%;
        height: 400px;
    }
    button {
        background-color: SteelBlue;
        color: white;
        width: 20%;
        padding: 15px;
        margin-top: 30px;
        font-size: 130%;
        border: none;
    }
    button:hover {
        background-color: Navy;
    }
    .tab {
        background-color: LightBlue;
        margin-right: 80px;
        padding: 10px;
    }
    #address, #contact {
        display: none;
    }
    #progress {
        background-color: LightGrey;
        width: 73%;
        margin-bottom: 10px;
    }
    #bar {
        background-color: Navy;
        width: 4%;
        height: 30px;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  42. Krok 42: Tabela promocji

    Kryteria: ,

    R.4.5 Ustawiono szerokość bloku bocznego 25%, banera, głównego oraz paska postępu 73% (width lub grid-template-columns lub flex) oraz 20% dla przycisków i 100% dla tabeli

    R.4.9 Ustawiono obramowanie tabeli linią kropkowaną o szerokości 1 px i kolorze Navy oraz brak obramowania dla przycisków

    ok. 1 min
    Polecenie z arkusza

    Dla tabeli: szerokość 100%, obramowanie linią kropkowaną o szerokości 1 px i kolorze Navy

    Linia kropkowana to dotted (kreskowana byłaby dashed). Ta reguła zamyka szerokości (R.4.5) i obramowania: kropkowana tabela i przyciski bez ramki (R.4.9).

    styl.css CSS zmienione: 4 linie
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    aside {
        width: 25%;
        height: 510px;
        margin: 0 1%;
        box-shadow: 4px 4px 5px DimGray;
    }
    header {
        width: 73%;
        height: 80px;
    }
    main {
        width: 73%;
        height: 400px;
    }
    button {
        background-color: SteelBlue;
        color: white;
        width: 20%;
        padding: 15px;
        margin-top: 30px;
        font-size: 130%;
        border: none;
    }
    button:hover {
        background-color: Navy;
    }
    .tab {
        background-color: LightBlue;
        margin-right: 80px;
        padding: 10px;
    }
    #address, #contact {
        display: none;
    }
    #progress {
        background-color: LightGrey;
        width: 73%;
        margin-bottom: 10px;
    }
    #bar {
        background-color: Navy;
        width: 4%;
        height: 30px;
    }
    table {
        width: 100%;
        border: 1px dotted Navy;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  43. Krok 43: Układ bloków zgodny z obrazem 2

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z obrazem 2 w arkuszu egzaminacyjnym, w bloku głównym może być widoczny jeden blok z kontrolkami, wszystkie trzy lub żaden (prawidłowo zastosowano właściwości CSS decydujące o układzie strony, np. float i clear albo display flex albo grid)

    ok. 2 min
    Polecenie z arkusza

    Podział strony na blok boczny i obok niego bloki: baner, główny, blok paska postępu oraz na dole blok stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML 5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2

    float: left dla czterech bloków. Blok boczny staje przy lewej krawędzi, baner (73%) mieści się obok niego. Blok główny nie zmieści się już w tym wierszu obok banera, więc przechodzi niżej - ale wysoki blok boczny wciąż tam stoi, dlatego blok główny ustawia się przy jego prawej krawędzi, pod banerem. Tak samo pasek postępu. clear: both stawia stopkę pod wszystkimi blokami pływającymi.

    Typowe błędy

    Bez float dla banera, bloku głównego i paska ich tło wchodzi pod blok boczny (pływający element przykrywa zwykłe bloki), choć tekst omija go z boku.

    styl.css CSS zmienione: 6 linii
    * {
        font-family: Cambria;
    }
    body {
        background-color: Linen;
    }
    aside, header, footer {
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    aside {
        width: 25%;
        height: 510px;
        margin: 0 1%;
        box-shadow: 4px 4px 5px DimGray;
    }
    header {
        width: 73%;
        height: 80px;
    }
    main {
        width: 73%;
        height: 400px;
    }
    button {
        background-color: SteelBlue;
        color: white;
        width: 20%;
        padding: 15px;
        margin-top: 30px;
        font-size: 130%;
        border: none;
    }
    button:hover {
        background-color: Navy;
    }
    .tab {
        background-color: LightBlue;
        margin-right: 80px;
        padding: 10px;
    }
    #address, #contact {
        display: none;
    }
    #progress {
        background-color: LightGrey;
        width: 73%;
        margin-bottom: 10px;
    }
    #bar {
        background-color: Navy;
        width: 4%;
        height: 30px;
    }
    table {
        width: 100%;
        border: 1px dotted Navy;
    }
    aside, header, main, #progress {
        float: left;
    }
    footer {
        clear: both;
    }
    Podgląd strony po tym kroku (rejestracja.html)
  44. Etap 4: JavaScript

    Kroki 44-51 · po tym etapie masz 43 z 43 kryteriów (pkt)

    Krok 44: Funkcja aktywująca: ukrycie wszystkich zakładek

    Kryteria:

    R.5.1 Skrypt zapisano w języku JavaScript i zawiera on przynajmniej jedną instrukcję

    ok. 2 min
    Polecenie z arkusza

    Funkcja aktywująca: ukrywa wszystkie zakładki

    Skrypt na końcu <body>, w znaczniku <script>. Funkcja showTab dostanie w parametrze tabId identyfikator zakładki, którą ma pokazać. Najpierw ukrywa wszystkie trzy: style.display = "none" - ta sama wartość, której używa arkusz stylów. Nikt jej jeszcze nie wywołuje, więc na stronie nic się nie zmienia.

    rejestracja.html HTML zmienione: 7 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button>Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
        <script>
            function showTab(tabId) {
                document.getElementById("client").style.display = "none";
                document.getElementById("address").style.display = "none";
                document.getElementById("contact").style.display = "none";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  45. Krok 45: Funkcja aktywująca: pokazanie wybranej zakładki

    ok. 1 min
    Polecenie z arkusza

    Pokazuje jedynie tę zakładkę (blok), której przycisk wybrano

    Po ukryciu wszystkich jedna linia pokazuje wybraną: display = "block" przywraca zwykły blok. Kolejność „najpierw ukryj wszystkie, potem pokaż jedną” sprawia, że nie trzeba pamiętać, która zakładka była otwarta.

    rejestracja.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button>Klient</button>
            <button>Adres</button>
            <button>Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button>Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
        <script>
            function showTab(tabId) {
                document.getElementById("client").style.display = "none";
                document.getElementById("address").style.display = "none";
                document.getElementById("contact").style.display = "none";
                document.getElementById(tabId).style.display = "block";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  46. Krok 46: Przyciski zakładek wywołują funkcję

    Kryteria: ,

    R.3.6 Przynajmniej jeden przycisk zakładek ma zdefiniowane zdarzenie onClick z przypisaną funkcją

    R.5.6 Po kliknięciu w dowolny przycisk (nazwę bloku) jest pokazywany odpowiadający mu blok, a pozostałe są ukrywane

    ok. 2 min
    Polecenie z arkusza

    Funkcja aktywująca jest wywoływana przez wciśnięcie dowolnego przycisku zakładki w bloku głównym

    Atrybut onclick z wywołaniem funkcji i identyfikatorem zakładki w apostrofach - atrybut stoi w cudzysłowach, więc tekst w środku musi mieć apostrofy. W podglądzie można już klikać zakładki: „Adres” pokazuje blok z ulicą (obraz 4), „Kontakt” - blok z telefonem (obraz 5).

    rejestracja.html HTML zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button onclick="showTab('client')">Klient</button>
            <button onclick="showTab('address')">Adres</button>
            <button onclick="showTab('contact')">Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button>Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
        <script>
            function showTab(tabId) {
                document.getElementById("client").style.display = "none";
                document.getElementById("address").style.display = "none";
                document.getElementById("contact").style.display = "none";
                document.getElementById(tabId).style.display = "block";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  47. Krok 47: Funkcja paska postępu: +12%

    Kryteria:

    R.5.3 Po opuszczeniu przynajmniej jednego pola edycyjnego pasek postępu zwiększa swoją szerokość o 12%

    ok. 2 min
    Polecenie z arkusza

    Funkcja modyfikuje właściwość stylu dla pustego bloku wewnątrz bloku paska postępu, w ten sposób, że jego szerokość jest zwiększana o 12%, np. po utracie focusa za pierwszym razem wartość wynosi 16%; za drugim razem jest to 28%, trzecim 40% i tak dalej

    Zmienna progress stoi poza funkcją, więc pamięta wartość między wywołaniami - zmienna zadeklarowana w środku funkcji przy każdym wywołaniu startowałaby od nowa. Startuje od 4 (szerokość z CSS), każde wywołanie dodaje 12, a nowa szerokość trafia do style.width jako tekst z jednostką: progress + "%" daje np. „16%”.

    rejestracja.html HTML zmienione: 7 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button onclick="showTab('client')">Klient</button>
            <button onclick="showTab('address')">Adres</button>
            <button onclick="showTab('contact')">Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button>Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
        <script>
            function showTab(tabId) {
                document.getElementById("client").style.display = "none";
                document.getElementById("address").style.display = "none";
                document.getElementById("contact").style.display = "none";
                document.getElementById(tabId).style.display = "block";
            }
    
            let progress = 4;
    
            function increaseProgress() {
                progress = progress + 12;
                document.getElementById("bar").style.width = progress + "%";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  48. Krok 48: Każde pole edycyjne wywołuje funkcję po utracie focusa

    Kryteria:

    R.3.5 Przynajmniej jedno pole edycyjne ma zdefiniowane zdarzenie onBlur lub onFocusOut z przypisaną funkcją

    ok. 2 min
    Polecenie z arkusza

    Dla wszystkich pól edycyjnych – utrata focusa powoduje wywołanie funkcji zmieniającej wartość paska postępu

    Utrata focusa to zdarzenie blur - kursor opuszcza pole (kliknięcie gdzie indziej albo klawisz Tab). Atrybut onblur dostaje wszystkie siedem pól edycyjnych: imię, nazwisko, data, ulica, numer, miasto i telefon; pole wyboru RODO nie jest polem edycyjnym. W podglądzie: kliknięcie w pole imienia i potem obok wydłuża pasek do 16%.

    rejestracja.html HTML zmienione: 7 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button onclick="showTab('client')">Klient</button>
            <button onclick="showTab('address')">Adres</button>
            <button onclick="showTab('contact')">Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane..." onblur="increaseProgress()">
                <p>Nazwisko</p>
                <input type="text" id="lastName" onblur="increaseProgress()">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate" onblur="increaseProgress()">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street" onblur="increaseProgress()">
                <p>Numer</p>
                <input type="number" id="houseNumber" onblur="increaseProgress()">
                <p>Miasto</p>
                <input type="text" id="city" onblur="increaseProgress()">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone" onblur="increaseProgress()">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button>Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
        <script>
            function showTab(tabId) {
                document.getElementById("client").style.display = "none";
                document.getElementById("address").style.display = "none";
                document.getElementById("contact").style.display = "none";
                document.getElementById(tabId).style.display = "block";
            }
    
            let progress = 4;
    
            function increaseProgress() {
                progress = progress + 12;
                document.getElementById("bar").style.width = progress + "%";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  49. Krok 49: Pasek nigdy szerszy niż 100%

    Kryteria:

    R.5.4 Szerokość paska postępu nie może być większa niż 100%, zastosowano warunek

    ok. 2 min
    Polecenie z arkusza

    Należy zabezpieczyć funkcję, aby wartość szerokości nigdy nie była wyższa niż 100%

    Rachunek: 4 + 8 · 12 = 100, więc po ósmej utracie focusa pasek jest pełny, a po dziewiątej miałby 112% i wyszedłby poza szare tło. Warunek if przycina wartość do 100. Stoi przed ustawieniem szerokości - do stylu trafia już poprawiona liczba.

    rejestracja.html HTML zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button onclick="showTab('client')">Klient</button>
            <button onclick="showTab('address')">Adres</button>
            <button onclick="showTab('contact')">Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane..." onblur="increaseProgress()">
                <p>Nazwisko</p>
                <input type="text" id="lastName" onblur="increaseProgress()">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate" onblur="increaseProgress()">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street" onblur="increaseProgress()">
                <p>Numer</p>
                <input type="number" id="houseNumber" onblur="increaseProgress()">
                <p>Miasto</p>
                <input type="text" id="city" onblur="increaseProgress()">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone" onblur="increaseProgress()">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button>Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
        <script>
            function showTab(tabId) {
                document.getElementById("client").style.display = "none";
                document.getElementById("address").style.display = "none";
                document.getElementById("contact").style.display = "none";
                document.getElementById(tabId).style.display = "block";
            }
    
            let progress = 4;
    
            function increaseProgress() {
                progress = progress + 12;
                if (progress > 100) {
                    progress = 100;
                }
                document.getElementById("bar").style.width = progress + "%";
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  50. Krok 50: Funkcja zatwierdzająca: wartości w konsoli

    Kryteria: ,

    R.5.7 Po kliknięciu w przycisk zatwierdzający wyświetlone są w konsoli przeglądarki wartości wpisane w pola edycyjne

    R.5.8 W funkcji zatwierdzającej zastosowano funkcję lub zestaw funkcji odwołujących się do wszystkich pól edycyjnych i pola wyboru na stronie

    ok. 3 min
    Polecenie z arkusza

    Funkcja zatwierdzająca pobiera wartość z każdego pola edycyjnego i pola wyboru. Wartości wyświetlane są w konsoli przeglądarki (obraz 6). Dla uproszczenia wszelką walidację należy pominąć

    Każde pole edycyjne odczytuje właściwość value elementu znalezionego przez getElementById, a pole wyboru - .checked (true albo false). Obraz 6 pokazuje przy zgodzie słowo „on”: to .value pola wyboru, które zawsze wynosi „on”, także gdy pole nie jest zaznaczone (sprawdzone w przeglądarce), więc nic nie mówi o zgodzie. console.log wypisuje jeden napis z wartościami po przecinku, jak na obrazie 6. Walidacji nie ma - tak każe arkusz.

    rejestracja.html HTML zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button onclick="showTab('client')">Klient</button>
            <button onclick="showTab('address')">Adres</button>
            <button onclick="showTab('contact')">Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane..." onblur="increaseProgress()">
                <p>Nazwisko</p>
                <input type="text" id="lastName" onblur="increaseProgress()">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate" onblur="increaseProgress()">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street" onblur="increaseProgress()">
                <p>Numer</p>
                <input type="number" id="houseNumber" onblur="increaseProgress()">
                <p>Miasto</p>
                <input type="text" id="city" onblur="increaseProgress()">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone" onblur="increaseProgress()">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button>Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
        <script>
            function showTab(tabId) {
                document.getElementById("client").style.display = "none";
                document.getElementById("address").style.display = "none";
                document.getElementById("contact").style.display = "none";
                document.getElementById(tabId).style.display = "block";
            }
    
            let progress = 4;
    
            function increaseProgress() {
                progress = progress + 12;
                if (progress > 100) {
                    progress = 100;
                }
                document.getElementById("bar").style.width = progress + "%";
            }
    
            function confirmData() {
                let firstName = document.getElementById("firstName").value;
                let lastName = document.getElementById("lastName").value;
                let birthDate = document.getElementById("birthDate").value;
                let street = document.getElementById("street").value;
                let houseNumber = document.getElementById("houseNumber").value;
                let city = document.getElementById("city").value;
                let phone = document.getElementById("phone").value;
                let rodo = document.getElementById("rodo").checked;
                console.log(firstName + ", " + lastName + ", " + birthDate + ", " + street + ", " + houseNumber + ", " + city + ", " + phone + ", " + rodo);
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  51. Krok 51: Przycisk „Zatwierdź dane” wywołuje funkcję

    Kryteria: ,

    R.3.7 Przycisk do zatwierdzenia danych ma zdefiniowane zdarzenie onClick z przypisaną funkcją

    R.5.9 Zastosowano znaczące nazewnictwo dla wszystkich zmiennych i funkcji w języku polskim lub angielskim. Nazwy odzwierciedlają cel zastosowania

    ok. 1 min
    Polecenie z arkusza

    Funkcja zatwierdzająca jest wywoływana po wybraniu przycisku „Zatwierdź dane”

    Atrybut onclick z wywołaniem confirmData(). Wynik widać w konsoli (F12, zakładka Console). Nazwy funkcji i zmiennych mówią, co robią i co przechowują (showTab, increaseProgress, confirmData, progress, houseNumber) - kryterium R.5.9.

    rejestracja.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button onclick="showTab('client')">Klient</button>
            <button onclick="showTab('address')">Adres</button>
            <button onclick="showTab('contact')">Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane..." onblur="increaseProgress()">
                <p>Nazwisko</p>
                <input type="text" id="lastName" onblur="increaseProgress()">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate" onblur="increaseProgress()">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street" onblur="increaseProgress()">
                <p>Numer</p>
                <input type="number" id="houseNumber" onblur="increaseProgress()">
                <p>Miasto</p>
                <input type="text" id="city" onblur="increaseProgress()">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone" onblur="increaseProgress()">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button onclick="confirmData()">Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
        <script>
            function showTab(tabId) {
                document.getElementById("client").style.display = "none";
                document.getElementById("address").style.display = "none";
                document.getElementById("contact").style.display = "none";
                document.getElementById(tabId).style.display = "block";
            }
    
            let progress = 4;
    
            function increaseProgress() {
                progress = progress + 12;
                if (progress > 100) {
                    progress = 100;
                }
                document.getElementById("bar").style.width = progress + "%";
            }
    
            function confirmData() {
                let firstName = document.getElementById("firstName").value;
                let lastName = document.getElementById("lastName").value;
                let birthDate = document.getElementById("birthDate").value;
                let street = document.getElementById("street").value;
                let houseNumber = document.getElementById("houseNumber").value;
                let city = document.getElementById("city").value;
                let phone = document.getElementById("phone").value;
                let rodo = document.getElementById("rodo").checked;
                console.log(firstName + ", " + lastName + ", " + birthDate + ", " + street + ", " + houseNumber + ", " + city + ", " + phone + ", " + rodo);
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  52. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 52-53 · po tym etapie masz 43 z 43 kryteriów (pkt)

    Krok 52: Pasek postępu liczony z wypełnionych pól

    ok. 4 min
    Polecenie z arkusza

    Funkcja jest uproszczona, zakładamy że każda utrata focusa kontrolki jest równa wpisaniu do niej danych i powoduje zwiększenie szerokości paska

    Arkusz świadomie upraszcza pasek, a skutek widać w przeglądarce: dziewięć razy kliknięte i opuszczone puste pole imienia daje w wersji egzaminacyjnej pasek 100% - formularz „wypełniony”, choć nic w nim nie ma. Poprawka: funkcja przy każdym wywołaniu liczy od nowa, ile pól edycyjnych ma niepustą wartość (trim pomija same spacje), i z tego wylicza szerokość: 4% + 12% za pole, najwyżej 100% (Math.min). Sprawdzone: puste pole opuszczone 9 razy - 4%, wpisane „Anna” - 16%, ponowne opuszczenie - nadal 16%, wyczyszczenie pola - z powrotem 4%. Zmienna globalna progress przestaje być potrzebna. Stara wersja zostaje w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - arkusz każe pominąć sprawdzanie, czy dane wpisano.

    rejestracja.html HTML zmienione: 16 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button onclick="showTab('client')">Klient</button>
            <button onclick="showTab('address')">Adres</button>
            <button onclick="showTab('contact')">Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane..." onblur="increaseProgress()">
                <p>Nazwisko</p>
                <input type="text" id="lastName" onblur="increaseProgress()">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate" onblur="increaseProgress()">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street" onblur="increaseProgress()">
                <p>Numer</p>
                <input type="number" id="houseNumber" onblur="increaseProgress()">
                <p>Miasto</p>
                <input type="text" id="city" onblur="increaseProgress()">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone" onblur="increaseProgress()">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button onclick="confirmData()">Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
        <script>
            function showTab(tabId) {
                document.getElementById("client").style.display = "none";
                document.getElementById("address").style.display = "none";
                document.getElementById("contact").style.display = "none";
                document.getElementById(tabId).style.display = "block";
            }
    
            const editFields = document.querySelectorAll("main input:not([type=checkbox])");
    
            // pasek liczy WYPEŁNIONE pola, a nie liczbę opuszczeń pola
            function increaseProgress() {
                let filled = 0;
                for (let field of editFields) {
                    if (field.value.trim() != "") {
                        filled = filled + 1;
                    }
                }
                let progress = Math.min(4 + filled * 12, 100);
                document.getElementById("bar").style.width = progress + "%";
            }
            /* Wersja z egzaminu - każda utrata focusa to +12%:
            let progress = 4;
            function increaseProgress() {
                progress = progress + 12;
                if (progress > 100) { progress = 100; }
                document.getElementById("bar").style.width = progress + "%";
            }
            */
    
            function confirmData() {
                let firstName = document.getElementById("firstName").value;
                let lastName = document.getElementById("lastName").value;
                let birthDate = document.getElementById("birthDate").value;
                let street = document.getElementById("street").value;
                let houseNumber = document.getElementById("houseNumber").value;
                let city = document.getElementById("city").value;
                let phone = document.getElementById("phone").value;
                let rodo = document.getElementById("rodo").checked;
                console.log(firstName + ", " + lastName + ", " + birthDate + ", " + street + ", " + houseNumber + ", " + city + ", " + phone + ", " + rodo);
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  53. Krok 53: Nasłuchiwacze zdarzeń i zgoda RODO przed zatwierdzeniem

    ok. 4 min
    Polecenie z arkusza

    Funkcja aktywująca jest wywoływana przez wciśnięcie dowolnego przycisku zakładki w bloku głównym

    Atrybuty onclick i siedem kopii onblur znikają z HTML-u. Przyciski zakładek niosą nazwę swojej zakładki w atrybucie data-tab, a pętla w skrypcie podpina im jeden nasłuchiwacz addEventListener("click", ...), który czyta ją przez dataset.tab. Druga pętla podpina zdarzenie blur wszystkim polom edycyjnym naraz - nowe pole w formularzu nie wymaga pamiętania o atrybucie. Funkcja zatwierdzająca dostaje jedno sprawdzenie, bez którego rejestracja w prawdziwym sklepie nie przejdzie: bez zaznaczonej zgody RODO pokazuje komunikat i nie wypisuje danych (sprawdzone w przeglądarce). Na egzaminie wystarczy wersja wcześniejsza - klucz w R.3.5 - R.3.7 mówi wprost o zdarzeniach onBlur i onClick, więc atrybuty są najpewniejszą formą, a walidację arkusz każe pominąć.

    rejestracja.html HTML zmienione: 24 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Sklep - rejestracja</title>
        <link rel="stylesheet" href="styl.css">
    </head>
    <body>
        <aside>
            <img src="obraz.png" alt="promocje">
            <h2>Sprawdź promocje</h2>
            <table>
                <tr>
                    <th>co?</th>
                    <th>ile taniej?</th>
                </tr>
                <tr>
                    <td>ubrania</td>
                    <td>15%</td>
                </tr>
                <tr>
                    <td>buty</td>
                    <td>25%</td>
                </tr>
            </table>
        </aside>
        <header>
            <h1>Zarejestruj się w sklepie</h1>
        </header>
        <main>
            <button data-tab="client">Klient</button>
            <button data-tab="address">Adres</button>
            <button data-tab="contact">Kontakt</button>
            <div class="tab" id="client">
                <p>Imię</p>
                <input type="text" id="firstName" placeholder="Wpisz dane...">
                <p>Nazwisko</p>
                <input type="text" id="lastName">
                <p>Data urodzenia</p>
                <input type="date" id="birthDate">
            </div>
            <div class="tab" id="address">
                <p>Ulica</p>
                <input type="text" id="street">
                <p>Numer</p>
                <input type="number" id="houseNumber">
                <p>Miasto</p>
                <input type="text" id="city">
            </div>
            <div class="tab" id="contact">
                <p>Numer komórkowy</p>
                <input type="tel" id="phone">
                <br>
                <input type="checkbox" id="rodo">
                <label for="rodo">Akceptuję RODO</label>
                <br>
                <button id="confirm">Zatwierdź dane</button>
            </div>
        </main>
        <section id="progress">
            <section id="bar"></section>
        </section>
        <footer>
            <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4>
        </footer>
        <script>
            function showTab(tabId) {
                document.getElementById("client").style.display = "none";
                document.getElementById("address").style.display = "none";
                document.getElementById("contact").style.display = "none";
                document.getElementById(tabId).style.display = "block";
            }
    
            const editFields = document.querySelectorAll("main input:not([type=checkbox])");
    
            // pasek liczy WYPEŁNIONE pola, a nie liczbę opuszczeń pola
            function increaseProgress() {
                let filled = 0;
                for (let field of editFields) {
                    if (field.value.trim() != "") {
                        filled = filled + 1;
                    }
                }
                let progress = Math.min(4 + filled * 12, 100);
                document.getElementById("bar").style.width = progress + "%";
            }
            /* Wersja z egzaminu - każda utrata focusa to +12%:
            let progress = 4;
            function increaseProgress() {
                progress = progress + 12;
                if (progress > 100) { progress = 100; }
                document.getElementById("bar").style.width = progress + "%";
            }
            */
    
            function confirmData() {
                let firstName = document.getElementById("firstName").value;
                let lastName = document.getElementById("lastName").value;
                let birthDate = document.getElementById("birthDate").value;
                let street = document.getElementById("street").value;
                let houseNumber = document.getElementById("houseNumber").value;
                let city = document.getElementById("city").value;
                let phone = document.getElementById("phone").value;
                let rodo = document.getElementById("rodo").checked;
                if (!rodo) {
                    alert("Zaznacz zgodę RODO, aby zatwierdzić dane");
                    return;
                }
                console.log(firstName + ", " + lastName + ", " + birthDate + ", " + street + ", " + houseNumber + ", " + city + ", " + phone + ", " + rodo);
            }
    
            // nasłuchiwacze zamiast atrybutów onclick i onblur w HTML-u
            for (let tabButton of document.querySelectorAll("button[data-tab]")) {
                tabButton.addEventListener("click", function () { showTab(tabButton.dataset.tab); });
            }
            for (let field of editFields) {
                field.addEventListener("blur", increaseProgress);
            }
            document.getElementById("confirm").addEventListener("click", confirmData);
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (rejestracja.html)
  54. Etap 6: Oddanie pracy

    Krok 54 · po tym etapie masz 43 z 43 kryteriów (pkt)

    Krok 54: Plik przeglądarka.txt i nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    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. Umieść go w folderze z numerem zdającego. Nagraj płytę z rezultatami pracy.

    W przeglądarka.txt wpisuje się nazwę przeglądarki, w której sprawdzana była strona.

    W folderze z numerem zdającego: import.png, kw1.jpg - kw4.jpg, kwerendy.txt, obraz.png (plakietka), przeglądarka.txt, rejestracja.html, styl.css. Płytę trzeba nagrać, sprawdzić jej odczyt i opisać numerem zdającego.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

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

Podgląd

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.

Autor rozwiązania: . Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony) (zasady wykorzystania). Treść arkusza i klucza oceniania pochodzi z CKE.