Przejdź do głównej treści
EE.09-05-20.06-SGCzerwiec 2020 · 46 kroków · ok. 86 min · 33 kryteria z klucza

Rozwiązanie krok po kroku: Salon fryzjerski z cennikiem strzyżenia (Wersja podstawowa)

Aplikacja internetowa salonu fryzjerskiego: baza egzamin2 zaimportowana z pliku i cztery zapytania - fryzjerzy z tabeli pracowników (WHERE), liczba usług fryzjerskich (COUNT), nowe konto bazy fryzjer (CREATE USER) i nadanie mu praw do jednej tabeli (GRANT). Do tego dwa zdjęcia przeskalowane z zachowaniem proporcji, dwie strony index.html i fryzura.html z pięcioma blokami (dwa po lewej, trzy po prawej) i stopką, style w styl2.css z efektem :hover na obrazach oraz skrypt w JavaScript, który podaje cenę strzyżenia dla długości włosów wybranej polem radio.

To arkusz EE.09 z czerwca 2020 - kwalifikacji formuły 2017, którą zastąpiła INF.03. 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 jest napisany najprościej, polami i zdarzeniami z tabeli arkusza (getElementById, checked, onclick, innerHTML). Strony nie mają PHP, więc podgląd od kroku z HTML-em to działająca strona - pola i przycisk można klikać.

To jest wersja podstawowa. W zakładce „Nowoczesny kod (flex, addEventListener)” jest drugi sposób rozwiązania tego samego arkusza: semantyczne znaczniki w kontenerze flex, zmienne CSS, etykiety <label>, ceny zapisane przy polach w atrybutach data- i skrypt w osobnym pliku podpięty przez addEventListener - obie wersje są zgodne z kluczem.

Baza i zdjęcia pochodzą z oryginalnego archiwum CKE egzamin2.zip (załącznik do pobrania na stronie arkusza, hasło w treści zadania). Zapytania i zrzuty są policzone na MariaDB 10.4 - tej samej, która jest w XAMPP, a uprawnienia nowego konta sprawdzone logowaniem na nie. Działanie skryptu sprawdzone w Chrome dla każdego pola radio.

Jak liczą się punkty. Klucz ma 33 kryteria (R.1.1 - R.5.4), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 25 punktów (75% z 33 to 24,75, zaokrąglone w górę) - można stracić 8 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 33 kryteriów (pkt)

    Krok 1: Folder zdającego i archiwum egzamin2.zip

    ok. 2 min
    Polecenie z arkusza

    Aby wykonać zadanie zaloguj się na konto Egzamin bez hasła. Na pulpicie znajdziesz archiwum ZIP o nazwie egzamin2.zip zabezpieczone hasłem: Salon[FryzUr] Archiwum należy rozpakować. Na pulpicie konta Egzamin utwórz folder. Jako nazwy folderu użyj swojego numeru PESEL. Umieść w tym folderze rozpakowane pliki.

    Na pulpicie tworzysz folder nazwany numerem PESEL - w tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora, Bartosz Bryniarski. Archiwum egzamin2.zip rozpakowujesz do tego folderu, podając hasło Salon[FryzUr] - z nawiasami kwadratowymi i wielkimi literami S, F i U. W środku są trzy pliki: egzamin2.sql, obraz1.jpg i obraz2.jpg.

    Do tego folderu trafia wszystko, co powstanie: zrzuty, kwerendy.txt, strony, style i przeskalowane zdjęcia.

    Typowe błędy

    Hasło przepisuj znak po znaku - nawiasy kwadratowe łatwo pomylić z okrągłymi, a wielkość liter ma znaczenie.

  2. Krok 2: XAMPP i pusta baza egzamin2

    ok. 2 min
    Polecenie z arkusza

    Uruchom usługi MySQL i Apache za pomocą XAMPP Control Panel. Za pomocą narzędzia phpMyAdmin wykonaj podane operacje na bazie danych: Utwórz bazę danych o nazwie egzamin2

    W XAMPP Control Panel Start przy Apache i MySQL, potem http://localhost/phpmyadmin, Nowa, nazwa egzamin2 (z cyfrą 2 na końcu), Utwórz. Strony w tym zadaniu nie łączą się z bazą - baza służy do importu i czterech zapytań.

  3. Krok 3: Import pliku egzamin2.sql i zrzut egzamin.jpg

    Kryteria:

    R.1.1 Wykonano import tabel do bazy danych egzamin2 , czynność udokumentowano plikiem o nazwie egzamin w formacie JPG. Zrzut zawiera cały obszar ekranu monitora z widocznym paskiem zadań

    ok. 3 min
    Polecenie z arkusza

    Do bazy egzamin2 zaimportuj tabele z pliku egzamin2.sql z rozpakowanego archiwum. Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie JPG pod nazwą egzamin, w folderze opisanym numerem PESEL. Nie kadruj zrzutu. Zrzut powinien obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel

    Zaznacz bazę egzamin2, karta Import, Wybierz plik → egzamin2.sql, Wykonaj. Plik tworzy sześć tabel, choć arkusz opisuje tylko dwie: kadra (5 pracowników) i uslugi (10 usług) oraz niepotrzebne w tym zadaniu matematycy, typy, uzytkownik i wyniki.

    Na zrzucie ma być widać zielony komunikat o sukcesie i tabele w lewym panelu. Zrzut całego ekranu z paskiem zadań zapisujesz jako egzamin.jpg - na przykład Print Screen, wklejenie do edytora grafiki i eksport do JPEG.

    Typowe błędy

    Zrzut importu ma być w JPG, a zrzuty zapytań w PNG - pomylony format to strata punktu. Wykadrowanego zrzutu albo zrzutu bez paska zadań klucz nie ocenia.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 3
  4. Krok 4: Zapytanie 1: pracownicy na stanowisku fryzjer

    Kryteria: ,

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

    R.1.3 Utworzono zapytanie 1 wybierające jedynie pola imie i nazwisko z tabeli kadra dla pracowników na stanowisku fryzjer. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko FROM kadra WHERE stanowisko = 'fryzjer'; oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczny jest jedynie jeden rekord z danymi Katarzyna Nowak

    ok. 3 min
    Polecenie z arkusza

    Zapisz i wykonaj zapytania SQL działające na bazie egzamin2. Zapytania zapisz w pliku kwerendy.txt, w folderze z numerem PESEL. Wykonaj zrzuty ekranu przedstawiające wyniki działania kwerend. Zrzuty zapisz w formacie PNG i nadaj im nazwy kw1, kw2, kw3, kw4. Zrzuty powinny obejmować cały ekran monitora, z widocznym paskiem zadań. Zapytanie 1: wybierająca jedynie pola imie i nazwisko z tabeli kadra dla pracowników na stanowisku fryzjer

    Zaznacz bazę egzamin2 i otwórz kartę SQL:

    • SELECT imie, nazwisko - tylko dwie kolumny; „jedynie” wyklucza SELECT *,
    • FROM kadra,
    • WHERE stanowisko = 'fryzjer' - tekst w apostrofach, dokładnie tak, jak zapisano go w bazie (małymi literami).

    Wynik to jeden rekord: Katarzyna Nowak - ten sam, który podaje klucz. Zapytanie kopiujesz do nowego pliku kwerendy.txt, zrzut całego ekranu - do kw1.png.

    Typowe błędy

    WHERE stanowisko = fryzjer bez apostrofów to porównanie z kolumną o nazwie fryzjer, której nie ma - błąd #1054.

    kwerendy.txt Tekst nowy plik
    -- Zapytanie 1
    SELECT imie, nazwisko FROM kadra WHERE stanowisko = 'fryzjer';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 4
  5. Krok 5: Zapytanie 2: liczba usług fryzjerskich

    Kryteria:

    R.1.4 Utworzono zapytanie 2 liczące liczbę rekordów w tabeli uslugi dla wszystkich usług fryzjerskich (rodzaj=2). W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT COUNT(*) FROM uslugi WHERE rodzaj=2; (zamiast * może wystąpić dowolna nazwa pola) oraz wynik działania zapytania udokumentowano zrzutem, na którym widoczna jest jedynie wartość 3 wynikająca z wydanego zapytania 2

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 2: liczące liczbę rekordów w tabeli uslugi dla wszystkich usług fryzjerskich (rodzaj odpowiada usługom fryzjerskim)

    Arkusz podaje znaczenie pola rodzaj: 1 - usługi kosmetyczne, 2 - fryzjerskie, 3 - inne.

    • SELECT COUNT(*) - funkcja COUNT liczy wiersze, które przeszły przez warunek,
    • FROM uslugi,
    • WHERE rodzaj = 2 - tylko usługi fryzjerskie.

    Fryzjerskie są: Farbowanie, Strzyzenie, Czesanie - wynik 3, taki sam jak w kluczu. Zrzut: kw2.png.

    Typowe błędy

    SUM(rodzaj) doda wartości pola (2 + 2 + 2 = 6) zamiast policzyć rekordy. Zapytanie ma działać dla dowolnych danych - warunek po polu rodzaj.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko FROM kadra WHERE stanowisko = 'fryzjer';
    
    -- Zapytanie 2
    SELECT COUNT(*) FROM uslugi WHERE rodzaj = 2;
    Podgląd strony po tym kroku
    Podgląd strony po kroku 5
  6. Krok 6: Zapytanie 3: konto fryzjer na localhost

    Kryteria:

    R.1.5 Utworzono zapytanie 3 tworzące użytkownika fryzjer na localhost z hasłem Fryz12 W pliku z kwerendami lub na zrzucie istnieje zapis np.: CREATE USER 'fryzjer'@'localhost' IDENTIFIED BY 'Fryz12'; oraz wynik działania zapytania udokumentowano zrzutem wskazującym na pomyślne dodanie użytkownika fryzjer nie uznajemy za spełnione jeśli nie jest widoczne hasło (np wygenerowano z kreatora)

    ok. 2 min
    Polecenie z arkusza

    Zapytanie 3: tworzące użytkownika fryzjer na localhost z hasłem Fryz12

    • CREATE USER 'fryzjer'@'localhost' - nowe konto serwera bazy danych (nie wiersz w tabeli); część @'localhost' oznacza, że konto może się łączyć tylko z tego samego komputera, na którym działa serwer,
    • IDENTIFIED BY 'Fryz12' - hasło konta; wielkość liter ma znaczenie.

    phpMyAdmin odpowiada „MySQL zwrócił pusty wynik” - polecenie niczego nie wybiera, więc to znak sukcesu. Zrzut: kw3.png.

    Typowe błędy

    Klucz nie uznaje konta założonego kreatorem Dodaj konto użytkownika, bo na zrzucie nie widać hasła - zapytanie wpisz na karcie SQL. Drugie wykonanie zgłosi błąd #1396 - konto już istnieje.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko FROM kadra WHERE stanowisko = 'fryzjer';
    
    -- Zapytanie 2
    SELECT COUNT(*) FROM uslugi WHERE rodzaj = 2;
    
    -- Zapytanie 3
    CREATE USER 'fryzjer'@'localhost' IDENTIFIED BY 'Fryz12';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 6
  7. Krok 7: Zapytanie 4: prawa CREATE, ALTER i SELECT do tabeli kadra

    Kryteria:

    R.1.6 Utworzono zapytanie 4 nadające jedynie prawa tworzenia i modyfikowania struktury tabeli oraz przeglądania danych w tabeli kadra bazy egzamin2 dla użytkownika fryzjer W pliku z kwerendami lub na zrzucie istnieje zapis np.: GRANT CREATE, ALTER, SELECT ON egzamin2.kadra TO 'fryzjer'@'localhost'; oraz wynik działania zapytania udokumentowano zrzutem wskazującym na pomyślne wykonanie zapytania 4

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 4: nadające prawa tworzenia i modyfikowania struktury tabeli oraz przeglądania danych w tabeli kadra bazy egzamin2 dla użytkownika fryzjer

    Każda część zdania arkusza to jedno prawo:

    • tworzenie struktury tabeli - CREATE,
    • modyfikowanie struktury - ALTER (dodawanie, zmiana i usuwanie kolumn),
    • przeglądanie danych - SELECT.

    Dalej ON egzamin2.kadra - zapis baza.tabela ogranicza prawa do jednej tabeli, i TO 'fryzjer'@'localhost' - konto podane tak samo jak przy tworzeniu, razem z hostem. Sprawdzone poleceniem SHOW GRANTS: konto ma GRANT SELECT, CREATE, ALTER ON egzamin2.kadra - serwer wypisuje prawa w swojej kolejności. Zrzut: kw4.png; plik kwerendy.txt ma komplet czterech zapytań.

    Typowe błędy

    UPDATE to zmiana danych, a nie struktury - klucz wymaga „jedynie” CREATE, ALTER, SELECT, więc dodatkowe prawo odbiera punkt.

    kwerendy.txt Tekst zmienione: 3 linie
    -- Zapytanie 1
    SELECT imie, nazwisko FROM kadra WHERE stanowisko = 'fryzjer';
    
    -- Zapytanie 2
    SELECT COUNT(*) FROM uslugi WHERE rodzaj = 2;
    
    -- Zapytanie 3
    CREATE USER 'fryzjer'@'localhost' IDENTIFIED BY 'Fryz12';
    
    -- Zapytanie 4
    GRANT CREATE, ALTER, SELECT ON egzamin2.kadra TO 'fryzjer'@'localhost';
    Podgląd strony po tym kroku
    Podgląd strony po kroku 7
  8. Etap 2: Grafika i strona HTML

    Kroki 8-28 · po tym etapie masz 17 z 33 kryteriów (pkt)

    Krok 8: Grafika: obraz1.jpg o wysokości 290 px

    Kryteria:

    R.2.1 Plik obraz1.jpg przeskalowano z zachowaniem proporcji do wysokości 290 px, odpowiadająca temu szerokość wynosi 232 px (± 2 px) lub plik obraz2.jpg przeskalowano z zachowaniem proporcji do szerokości 600 px, odpowiadająca temu wysokość wynosi 262 px (± 2 px)

    ok. 2 min
    Polecenie z arkusza

    Plik obraz1.jpg, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego wysokość wynosiła dokładnie 290 px

    Oryginał ma 352 × 440 px. W GIMP-ie Obraz → Skaluj obraz, łańcuch między szerokością a wysokością złączony (to jest zachowanie proporcji), wysokość 290 - szerokość przelicza się sama: 352 × 290 / 440 = 232 px. Klucz podaje właśnie 232 px (±2). Plik → Nadpisz obraz1.jpg.

    Typowe błędy

    Ustawienie wymiarów atrybutem height albo w CSS nie zmienia pliku - klucz mierzy sam plik.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 8
  9. Krok 9: Grafika: obraz2.jpg o szerokości 600 px

    ok. 2 min
    Polecenie z arkusza

    Plik obraz2.jpg, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji tak, aby jego szerokość wynosiła dokładnie 600 px

    Oryginał ma 1000 × 436 px. Ta sama operacja, tym razem wpisujesz szerokość 600 - wysokość: 436 × 600 / 1000 = 261,6, czyli 262 px (klucz: 262 px ±2). Wystarczy jeden z dwóch obrazów, żeby dostać R.2.1, ale arkusz wymaga obu.

    Podgląd strony po tym kroku
    Podgląd strony po kroku 9
  10. Krok 10: Plik index.html

    ok. 2 min
    Polecenie z arkusza

    Składa się ze stron o nazwach index.html oraz fryzura.html. Obie strony różnią się jedynie drugim blokiem lewym

    Najpierw powstaje komplet strony index.html, a plik fryzura.html będzie jej kopią z innym drugim blokiem lewym - tak nie trzeba pisać wspólnych części dwa razy. <!DOCTYPE html> oznacza HTML5, lang="pl" mówi przeglądarce, że treść jest po polsku. Strony nie potrzebują PHP - można je otworzyć prosto z dysku.

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

    Kryteria:

    R.2.2 Witrynę internetową zapisano w plikach HTML o nazwie index i fryzura oraz na przynajmniej jednej stronie zastosowano właściwy standard kodowania polskich znaków

    ok. 1 min
    Polecenie z arkusza

    Zastosowany właściwy standard kodowania polskich znaków

    <meta charset="UTF-8"> jako pierwszy element <head>, plik zapisany w UTF-8 (w Notepad++ menu Kodowanie). Nazwy plików index i fryzura razem z kodowaniem dają R.2.2 - drugi plik powstanie za kilka kroków.

    index.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 (index.html)
  12. Krok 12: Tytuł strony

    Kryteria:

    R.2.3 Nadano tytuł: "Usługi fryzjerskie” przynajmniej dla jednej strony

    ok. 1 min
    Polecenie z arkusza

    Tytuł strony widoczny na karcie przeglądarki: „Usługi fryzjerskie”

    <title> w <head> - napis na karcie przeglądarki. Nagłówek na stronie to inny tekst: „SALON FRYZJERSKI”.

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

    Kryteria:

    R.3.5 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl2 , formatowanie 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 styl2.css prawidłowo połączony z kodem strony

    <link rel="stylesheet" href="styl2.css"> w <head> - nazwa pliku z cyfrą 2. Plik stylów powstanie po HTML-u. Wszystkie style idą do tego pliku - klucz R.3.5 wymaga, żeby formatowanie pochodziło jedynie z niego.

    Typowe błędy

    Odnośnik do styl.css (bez dwójki) nie wczyta stylów. Kropka zamiast # przy identyfikatorze bloku też odbiera R.3.5, nawet gdy reszta stylów działa.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  14. Krok 14: Bloki: dwa lewe, trzy prawe i stopka

    Kryteria:

    R.2.4 Wygląd przynajmniej jednej strony zdefiniowano dzieląc ją na bloki: dwa bloki po lewej stronie i trzy po prawej, poniżej stopka. Zastosowano znaczniki sekcji

    ok. 3 min
    Polecenie z arkusza

    Podział strony na bloki: dwa bloki po lewej stronie i trzy po prawej, poniżej stopka. Podział zrealizowany za pomocą znaczników sekcji tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z Obrazem 2

    Pięć znaczników <section> z identyfikatorami left1, left2, right1, right2, right3 (nazwy po angielsku - arkusz ich nie narzuca) i <footer> na stopkę.

    Kolejność w kodzie jest celowa: lewy 1, prawy 1, prawy 2, lewy 2, prawy 3. Bloki ustawi float - lewe do lewej krawędzi, prawe do prawej - a pływający blok nie może zacząć się wyżej niż blok pływający zapisany przed nim. Gdyby lewy 2 stał w kodzie przed prawym 2, prawy 2 zacząłby się dopiero na wysokości 400 px, pod pierwszym lewym blokiem. Zgodność z obrazem 2 sprawdzi pomiar w kroku z układem.

    index.html HTML zmienione: 12 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
        </section>
        <section id="right1">
        </section>
        <section id="right2">
        </section>
        <section id="left2">
        </section>
        <section id="right3">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  15. Krok 15: Pierwszy blok lewy: nagłówek-odnośnik „SALON FRYZJERSKI”

    Kryteria:

    R.3.3 Na przynajmniej jednej stronie odnośnik "SALON FRYZJERSKI" prowadzi do strony index.html

    ok. 2 min
    Polecenie z arkusza

    Zawartość pierwszego bloku po lewej stronie: Nagłówek drugiego stopnia o treści „SALON FRYZJERSKI”, który jest jednocześnie odnośnikiem do strony index.html

    Nagłówek drugiego stopnia to <h2>, a odnośnik <a href="index.html"> stoi wewnątrz nagłówka i obejmuje jego tekst. Ścieżka względna (sama nazwa pliku), bo strony leżą w jednym folderze - klucz wymaga ścieżki względnej. Na fryzura.html ten nagłówek będzie drogą powrotu na stronę główną.

    Typowe błędy

    Ścieżka bezwzględna file:///C:/Users/Egzamin/Desktop/... działa tylko na komputerze zdającego - egzaminator otwiera pliki z płyty i klucz jej nie uznaje.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
        </section>
        <section id="right1">
        </section>
        <section id="right2">
        </section>
        <section id="left2">
        </section>
        <section id="right3">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  16. Krok 16: Pierwszy blok lewy: zdjęcie z tekstem „Czesanie”

    ok. 1 min
    Polecenie z arkusza

    Obraz o nazwie obraz2.jpg z tekstem alternatywnym „Czesanie”

    <img> z plikiem przeskalowanym do 600 px szerokości i atrybutem alt - tekstem, który przeczyta czytnik ekranu i który pojawi się, gdy plik się nie wczyta. W HTML5 <img> nie ma znacznika zamykającego.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
        </section>
        <section id="right2">
        </section>
        <section id="left2">
        </section>
        <section id="right3">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  17. Krok 17: Pierwszy blok prawy: nagłówek „MENU”

    ok. 1 min
    Polecenie z arkusza

    Zawartość pierwszego bloku po prawej stronie: Nagłówek drugiego stopnia o treści „MENU”

    Drugi nagłówek <h2> na stronie - ten bez odnośnika.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
        </section>
        <section id="left2">
        </section>
        <section id="right3">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  18. Krok 18: Drugi blok prawy: lista numerowana

    ok. 1 min
    Polecenie z arkusza

    Zawartość drugiego bloku po prawej stronie: Lista numerowana (uporządkowana) z elementami: Strzyżenie, Czesanie, Koloryzacja

    Lista numerowana (uporządkowana) to <ol>, każdy element w <li> ze znacznikiem zamykającym. Numery 1, 2, 3 dopisuje przeglądarka.

    index.html HTML zmienione: 5 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li>Strzyżenie</li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
        </section>
        <section id="right3">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  19. Krok 19: Lista punktowana zagnieżdżona w „Strzyżenie”

    Kryteria:

    R.2.7 Na przynajmniej jednej stronie w drugim bloku prawym umieszczono listę numerowaną z trzema elementami, pierwszy z elementów ma zagnieżdżoną listę punktowaną z czterema elementami, zastosowano znaczniki <ul>, <ol>, <li> oraz ich zamknięcia

    ok. 2 min
    Polecenie z arkusza

    Element „Strzyżenie” ma zagnieżdżoną listę punktowaną (nieuporządkowaną) z elementami: krótkie, średnie, półdługie, długie

    Lista punktowana (nieuporządkowana) to <ul>. „Zagnieżdżona w elemencie” znaczy, że stoi wewnątrz <li> „Strzyżenie” - przed jego znacznikiem zamykającym </li>. Przeglądarka sama wcina ją i rysuje punktory w kształcie kółek, jak na obrazie 2. Komplet <ol>, <ul>, <li> z zamknięciami to R.2.7.

    Typowe błędy

    <ul> wstawiona między dwa <li> (po </li>) to błąd składni HTML - lista nie należy wtedy do żadnego elementu, choć przeglądarka może ją pokazać podobnie.

    index.html HTML zmienione: 8 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li>Strzyżenie
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
        </section>
        <section id="right3">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  20. Krok 20: Odnośnik „Strzyżenie” do fryzura.html

    Kryteria:

    R.3.2 Na przynajmniej jednej stronie odnośnik "Strzyżenie" prowadzi do strony fryzura.html

    ok. 1 min
    Polecenie z arkusza

    Tekst elementu „Strzyżenie” jest równocześnie odnośnikiem do strony fryzura.html

    Sam tekst elementu obejmujesz znacznikiem <a href="fryzura.html"> - lista zagnieżdżona zostaje poza odnośnikiem. Ścieżka względna, jak przy nagłówku.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
        </section>
        <section id="right3">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  21. Krok 21: Trzeci blok prawy: zdjęcie fryzjerki

    Kryteria:

    R.2.6 Na przynajmniej jednej stronie umieszczono w trzecim bloku prawym obraz obraz1.jpg z tekstem alternatywnym "Fryzjer" oraz umieszczono w pierwszym lewym bloku obraz obraz2.jpg z tekstem alternatywnym "Czesanie"

    ok. 1 min
    Polecenie z arkusza

    Zawartość trzeciego bloku po prawej stronie Obraz o nazwie obraz1.jpg z tekstem alternatywnym „Fryzjer”

    Drugi <img>, w bloku right3. Oba obrazy z właściwymi tekstami alternatywnymi w swoich blokach to R.2.6.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  22. Krok 22: Stopka z autorem strony

    ok. 1 min
    Polecenie z arkusza

    Zawartość stopki: Akapit (paragraf) o treści „Autor: ”, dalej wstawiony numer PESEL zdającego

    Akapit <p> w <footer>. Na egzaminie po dwukropku wpisujesz swój numer PESEL. W tym rozwiązaniu w jego miejscu stoi imię i nazwisko autora: Bartosz Bryniarski.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  23. Krok 23: Drugi blok lewy: nagłówek „Kontakt: 111 222 333”

    ok. 1 min
    Polecenie z arkusza

    Zawartość drugiego bloku po lewej stronie dla index.html: Nagłówek piątego stopnia o treści „Kontakt: 111 222 333”

    Piątego stopnia to <h5> - mały, pogrubiony napis, jak na obrazie 2.

    index.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h5>Kontakt: 111 222 333</h5>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  24. Krok 24: Akapit powitalny z łamaniem wiersza

    ok. 2 min
    Polecenie z arkusza

    Akapit (paragraf) o treści zgodnej z Obrazem 2, łamanie wiersza zgodne z Obrazem 2 Treść akapitu: „Witaj! Miło nam, że odwiedziłeś nasz salon. Zapoznaj się z ofertą i sprawdź promocje!”

    Na obrazie 2 tekst łamie się po pierwszym zdaniu: „…nasz salon.” i w nowej linii „Zapoznaj się…”. Takie łamanie wymuszasz znacznikiem <br> - sam enter w kodzie HTML przeglądarka traktuje jak spację. Strona index.html jest kompletna.

    Typowe błędy

    Dwa osobne akapity zamiast <br> dadzą większy odstęp między liniami niż na obrazie 2.

    index.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h5>Kontakt: 111 222 333</h5>
            <p>Witaj! Miło nam, że odwiedziłeś nasz salon.<br>
            Zapoznaj się z ofertą i sprawdź promocje!</p>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (index.html)
  25. Krok 25: Strona fryzura.html: kopia z nagłówkiem o promocji

    Kryteria:

    R.2.5 Na przynajmniej jednej stronie w pierwszym bloku lewym zapisano nagłówek h2: "SALON FRYZJERSKI", w pierwszym bloku prawym zapisano nagłówek h2: "MENU", w bloku drugim lewym nagłówek h5: "Kontakt: 111 222 333" i nagłówek h3: "Dziś promocja na strzyżenie włosów" oraz przynajmniej jeden paragraf (znacznik <p>)

    ok. 2 min
    Polecenie z arkusza

    Wygląd drugiego bloku po lewej stronie dla fryzura.html przedstawiono na Obrazie 3, jego zawartość to: Nagłówek trzeciego stopnia o treści „Dziś promocja na strzyżenie włosów”

    Plik index.html zapisujesz jako fryzura.html (Plik → Zapisz jako) i w bloku left2 usuwasz nagłówek z telefonem i akapit, a wstawiasz nagłówek <h3>. Reszta strony zostaje bez zmian - arkusz mówi, że strony różnią się jedynie drugim blokiem lewym.

    Komplet nagłówków z klucza - <h2> „SALON FRYZJERSKI”, <h2> „MENU”, <h5> z telefonem, <h3> o promocji - i akapit to R.2.5.

    fryzura.html HTML nowy plik
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h3>Dziś promocja na strzyżenie włosów</h3>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  26. Krok 26: Cztery pola radio jedno pod drugim

    ok. 3 min
    Polecenie z arkusza

    Cztery pola radio jedno pod drugim z podpisami: Krótkie, Średnie, Półdługie, Długie. W danym momencie tylko jedno pole radio może być zaznaczone

    Pole radio to <input type="radio">, podpis stoi zaraz za nim, a <br> przenosi następne pole do nowej linii.

    To, że zaznaczone może być tylko jedno pole, zapewnia wspólny atrybut name="length" - przeglądarka traktuje pola o tej samej nazwie jako jedną grupę i zaznaczenie jednego odznacza pozostałe. Każde pole dostaje też własny identyfikator (short, medium, halflong, long) - po nim skrypt sprawdzi, które pole jest zaznaczone. Sprawdzone w Chrome: po kliknięciu „Długie” pole „Krótkie” traci zaznaczenie.

    Typowe błędy

    Bez wspólnego name (albo z czterema różnymi nazwami) da się zaznaczyć wszystkie cztery pola naraz - klucz R.2.8 wymaga, żeby zaznaczone było tylko jedno.

    fryzura.html HTML zmienione: 4 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h3>Dziś promocja na strzyżenie włosów</h3>
            <input type="radio" name="length" id="short"> Krótkie<br>
            <input type="radio" name="length" id="medium"> Średnie<br>
            <input type="radio" name="length" id="halflong"> Półdługie<br>
            <input type="radio" name="length" id="long"> Długie<br>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  27. Krok 27: Przycisk „Odkryj promocję”

    Kryteria:

    R.2.8 Na stronie fryzura.html w drugim bloku lewym umieszczono cztery pola radio oraz przycisk o treści: "Odkryj promocję" oraz w danym momencie tylko jedno pole radio może być zaznaczone

    ok. 1 min
    Polecenie z arkusza

    Poniżej przycisk o treści „Odkryj promocję”

    <button> poza formularzem niczego nie wysyła - zrobi to, co każe mu skrypt. Cztery pola radio w jednej grupie i przycisk w drugim bloku lewym to R.2.8.

    fryzura.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h3>Dziś promocja na strzyżenie włosów</h3>
            <input type="radio" name="length" id="short"> Krótkie<br>
            <input type="radio" name="length" id="medium"> Średnie<br>
            <input type="radio" name="length" id="halflong"> Półdługie<br>
            <input type="radio" name="length" id="long"> Długie<br>
            <button>Odkryj promocję</button>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  28. Krok 28: Miejsce na wynik skryptu

    ok. 1 min
    Polecenie z arkusza

    Poniżej wyniki działania skryptu

    Pusty akapit z identyfikatorem result pod przyciskiem - skrypt wpisze do niego cenę.

    fryzura.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h3>Dziś promocja na strzyżenie włosów</h3>
            <input type="radio" name="length" id="short"> Krótkie<br>
            <input type="radio" name="length" id="medium"> Średnie<br>
            <input type="radio" name="length" id="halflong"> Półdługie<br>
            <input type="radio" name="length" id="long"> Długie<br>
            <button>Odkryj promocję</button>
            <p id="result"></p>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  29. Etap 3: Styl CSS

    Kroki 29-39 · po tym etapie masz 28 z 33 kryteriów (pkt)

    Krok 29: Plik styl2.css: krój Helvetica dla całej strony

    Kryteria:

    R.4.1 Ustawiono domyślny krój czcionki dla całej strony na Helvetica (dla selektora * lub body, lub html, lub kontenera całej strony)

    ok. 1 min
    Polecenie z arkusza

    Cechy formatowania CSS, działające na obu stronach: Domyślne dla całej strony: krój czcionki Helvetica

    Nowy plik styl2.css - obie strony mają do niego odnośnik, więc każda reguła działa na obu. Selektor * obejmuje wszystkie elementy, także przycisk, który kroju po body nie dziedziczy (R.4.1). Windows nie ma Helvetiki - przeglądarka podstawi podobny krój bezszeryfowy (zwykle Arial), dlatego obraz 2 wygląda jak Arial.

    styl2.css CSS nowy plik
    * {
        font-family: Helvetica;
    }
    Podgląd strony po tym kroku (index.html)
  30. Krok 30: Pierwszy blok lewy: wymiary, tło, wyrównanie

    ok. 1 min
    Polecenie z arkusza

    Dla pierwszego lewego bloku: wysokość 400 px, szerokość 70%, kolor tła Snow, wyrównanie tekstu do środka

    Selektor #left1 - krzyżyk, bo left1 to identyfikator. text-align: center wyśrodkowuje nagłówek i obraz (obraz jest elementem w linii, więc słucha wyrównania tekstu).

    styl2.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    #left1 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        text-align: center;
    }
    Podgląd strony po tym kroku (index.html)
  31. Krok 31: Drugi blok lewy: wymiary, tło, rozmiar czcionki

    Kryteria:

    R.4.7 Ustawiono rozmiar czcionki na 150% dla drugiego lewego bloku

    ok. 1 min
    Polecenie z arkusza

    Dla drugiego lewego bloku: wysokość 400 px, szerokość 70%, kolor tła Snow, rozmiar czcionki 150%

    Bez wyrównania - tekst zostaje przy lewej krawędzi, jak na obrazie 2. Rozmiar 150% powiększa akapit, pola i podpisy na fryzura.html (R.4.7). Lewa kolumna ma 400 + 400 = 800 px.

    styl2.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    #left1 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        text-align: center;
    }
    #left2 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        font-size: 150%;
    }
    Podgląd strony po tym kroku (index.html)
  32. Krok 32: Pierwszy blok prawy

    ok. 1 min
    Polecenie z arkusza

    Dla pierwszego prawego bloku: wysokość 150 px, szerokość 30%, kolor tła SteelBlue, biały kolor czcionki, wyrównanie tekstu do środka

    Kolor czcionki to właściwość color, wyrównanie - text-align: center.

    styl2.css CSS zmienione: 7 linii
    * {
        font-family: Helvetica;
    }
    #left1 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        text-align: center;
    }
    #left2 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        font-size: 150%;
    }
    #right1 {
        height: 150px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    Podgląd strony po tym kroku (index.html)
  33. Krok 33: Drugi blok prawy

    ok. 1 min
    Polecenie z arkusza

    Dla drugiego prawego bloku: wysokość 350 px, szerokość 30%, kolor tła SteelBlue, biały kolor czcionki

    To samo tło co blok wyżej - na obrazie 2 bloki z menu i listą zlewają się w jedną granatową kolumnę. Odnośnik „Strzyżenie” zostaje w kolorze odnośnika (niebieski albo fioletowy po odwiedzeniu) - color bloku go nie zmienia.

    styl2.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    #left1 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        text-align: center;
    }
    #left2 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        font-size: 150%;
    }
    #right1 {
        height: 150px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    #right2 {
        height: 350px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
    }
    Podgląd strony po tym kroku (index.html)
  34. Krok 34: Trzeci blok prawy

    Kryteria: ,

    R.4.4 Ustawiono wysokość bloków lewych na 400px oraz bloków prawych kolejno na 150px, 350px, 300px

    R.4.5 Ustawiono szerokość bloków lewych na 70% oraz prawych na 30%

    ok. 1 min
    Polecenie z arkusza

    Dla trzeciego prawego bloku: wysokość 300 px, szerokość 30%, kolor tła Snow, wyrównanie tekstu do środka

    Prawa kolumna ma 150 + 350 + 300 = 800 px, tyle samo co lewa. Wysokości wszystkich pięciu bloków (R.4.4) i szerokości 70% i 30% (R.4.5) są ustawione.

    styl2.css CSS zmienione: 6 linii
    * {
        font-family: Helvetica;
    }
    #left1 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        text-align: center;
    }
    #left2 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        font-size: 150%;
    }
    #right1 {
        height: 150px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    #right2 {
        height: 350px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
    }
    #right3 {
        height: 300px;
        width: 30%;
        background-color: Snow;
        text-align: center;
    }
    Podgląd strony po tym kroku (index.html)
  35. Krok 35: Stopka: tło i biały tekst

    Kryteria: , ,

    R.4.2 Ustawiono kolor tła SteelBlue dla pierwszego i drugiego prawego bloku oraz stopki, a kolor Snow dla pozostałych bloków

    R.4.3 Ustawiono biały kolor czcionki dla pierwszego i drugiego prawego bloku oraz stopki

    R.4.6 Ustawiono wyrównanie tekstu do środka dla bloków pierwszego lewego oraz pierwszego i trzeciego prawego

    ok. 2 min
    Polecenie z arkusza

    Dla stopki: kolor tła SteelBlue, biały kolor czcionki

    Selektor znacznika footer (bez krzyżyka - stopka nie ma identyfikatora). Komplet teł: SteelBlue w blokach prawych 1 i 2 oraz stopce, Snow w pozostałych (R.4.2), biały tekst w tych samych trzech miejscach (R.4.3), wyrównanie do środka w bloku lewym 1 i prawych 1 i 3 (R.4.6).

    styl2.css CSS zmienione: 4 linie
    * {
        font-family: Helvetica;
    }
    #left1 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        text-align: center;
    }
    #left2 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        font-size: 150%;
    }
    #right1 {
        height: 150px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    #right2 {
        height: 350px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
    }
    #right3 {
        height: 300px;
        width: 30%;
        background-color: Snow;
        text-align: center;
    }
    footer {
        background-color: SteelBlue;
        color: white;
    }
    Podgląd strony po tym kroku (index.html)
  36. Krok 36: Układ: dwie kolumny bloków, stopka pod nimi

    Kryteria:

    R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest w pełni zgodny z Obrazem 2 w arkuszu egzaminacyjnym

    ok. 3 min
    Polecenie z arkusza

    Podział strony na bloki: dwa bloki po lewej stronie i trzy po prawej, poniżej stopka. Podział zrealizowany za pomocą znaczników sekcji tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z Obrazem 2

    Trzy reguły:

    • bloki lewe float: left przyklejają się do lewej krawędzi, a clear: left każe drugiemu lewemu zejść pod pierwszy,
    • bloki prawe float: right i clear: right - każdy kolejny prawy schodzi pod poprzedni,
    • stopka z clear: both zaczyna się pod najniższym blokiem obu kolumn.

    Kolejność bloków w kodzie (lewy 1, prawy 1, prawy 2, lewy 2, prawy 3) z kroku z sekcjami sprawia, że prawa kolumna nie czeka na lewą. Zmierzone w Chrome przy szerokości okna 1280 px: kolumny mają 70% i 30% szerokości, prawe bloki zaczynają się 0, 150 i 500 px od góry, lewy 2 - 400 px od góry, a stopka - 800 px od góry, pod obiema kolumnami (R.3.1). Wersja nowoczesna pokazuje ten sam układ na flex.

    Typowe błędy

    Wszystkie bloki z float: left (bez clear) ustawią się w jednym rzędzie i zawiną w przypadkowych miejscach - układ z obrazu 2 przepada.

    styl2.css CSS zmienione: 11 linii
    * {
        font-family: Helvetica;
    }
    #left1 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        text-align: center;
    }
    #left2 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        font-size: 150%;
    }
    #right1 {
        height: 150px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    #right2 {
        height: 350px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
    }
    #right3 {
        height: 300px;
        width: 30%;
        background-color: Snow;
        text-align: center;
    }
    footer {
        background-color: SteelBlue;
        color: white;
    }
    #left1, #left2 {
        float: left;
        clear: left;
    }
    #right1, #right2, #right3 {
        float: right;
        clear: right;
    }
    footer {
        clear: both;
    }
    Podgląd strony po tym kroku (index.html)
  37. Krok 37: Nagłówki drugiego stopnia: 250%

    Kryteria:

    R.4.8 Ustawiono styl dla nagłówka h2: rozmiar czcionki 250%

    ok. 1 min
    Polecenie z arkusza

    Dla nagłówka drugiego stopnia: rozmiar czcionki 250%

    Selektor h2 działa na oba nagłówki - „SALON FRYZJERSKI” i „MENU” (R.4.8). Procent liczy się od rozmiaru czcionki bloku, w którym stoi nagłówek.

    styl2.css CSS zmienione: 3 linie
    * {
        font-family: Helvetica;
    }
    #left1 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        text-align: center;
    }
    #left2 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        font-size: 150%;
    }
    #right1 {
        height: 150px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    #right2 {
        height: 350px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
    }
    #right3 {
        height: 300px;
        width: 30%;
        background-color: Snow;
        text-align: center;
    }
    footer {
        background-color: SteelBlue;
        color: white;
    }
    #left1, #left2 {
        float: left;
        clear: left;
    }
    #right1, #right2, #right3 {
        float: right;
        clear: right;
    }
    footer {
        clear: both;
    }
    h2 {
        font-size: 250%;
    }
    Podgląd strony po tym kroku (index.html)
  38. Krok 38: Obraz: marginesy wewnętrzne

    Kryteria:

    R.4.9 Ustawiono styl dla obrazu: marginesy wewnętrzne (padding) 4px

    ok. 1 min
    Polecenie z arkusza

    Dla obrazu: marginesy wewnętrzne 4 px

    Margines wewnętrzny to padding - odstęp między zdjęciem a jego krawędzią (R.4.9). Na razie go nie widać, bo obraz nie ma ramki - pojawi się w następnym kroku.

    styl2.css CSS zmienione: 3 linie
    * {
        font-family: Helvetica;
    }
    #left1 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        text-align: center;
    }
    #left2 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        font-size: 150%;
    }
    #right1 {
        height: 150px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    #right2 {
        height: 350px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
    }
    #right3 {
        height: 300px;
        width: 30%;
        background-color: Snow;
        text-align: center;
    }
    footer {
        background-color: SteelBlue;
        color: white;
    }
    #left1, #left2 {
        float: left;
        clear: left;
    }
    #right1, #right2, #right3 {
        float: right;
        clear: right;
    }
    footer {
        clear: both;
    }
    h2 {
        font-size: 250%;
    }
    img {
        padding: 4px;
    }
    Podgląd strony po tym kroku (index.html)
  39. Krok 39: Obraz pod kursorem: ramka SteelBlue

    Kryteria:

    R.4.10 Ustawiono styl dla obrazu z pseudoklasą hover: marginesy wewnętrzne (padding) 3 px oraz obramowanie linią ciągłą o szerokości 1 px i kolorze SteelBlue

    ok. 2 min
    Polecenie z arkusza

    W momencie, gdy kursor znajduje się na obrazie, styl obrazu zmienia się na: marginesy wewnętrzne 3 px oraz obramowanie linią ciągłą o szerokości 1 px i kolorze SteelBlue (efekt ten jest widoczny na Obrazie 2)

    Pseudoklasa :hover działa, gdy kursor jest nad elementem. border: 1px solid SteelBlue to ramka: grubość, linia ciągła (solid), kolor (R.4.10).

    Padding maleje z 4 do 3 px, bo ramka 1 px dochodzi do zewnętrznego rozmiaru obrazu: 3 + 1 = 4 px - obraz pod kursorem ma te same wymiary co bez niego i nic na stronie nie przeskakuje. Najedź kursorem na zdjęcie w podglądzie.

    styl2.css CSS zmienione: 4 linie
    * {
        font-family: Helvetica;
    }
    #left1 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        text-align: center;
    }
    #left2 {
        height: 400px;
        width: 70%;
        background-color: Snow;
        font-size: 150%;
    }
    #right1 {
        height: 150px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
        text-align: center;
    }
    #right2 {
        height: 350px;
        width: 30%;
        background-color: SteelBlue;
        color: white;
    }
    #right3 {
        height: 300px;
        width: 30%;
        background-color: Snow;
        text-align: center;
    }
    footer {
        background-color: SteelBlue;
        color: white;
    }
    #left1, #left2 {
        float: left;
        clear: left;
    }
    #right1, #right2, #right3 {
        float: right;
        clear: right;
    }
    footer {
        clear: both;
    }
    h2 {
        font-size: 250%;
    }
    img {
        padding: 4px;
    }
    img:hover {
        padding: 3px;
        border: 1px solid SteelBlue;
    }
    Podgląd strony po tym kroku (index.html)
  40. Etap 4: Skrypt JavaScript

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

    Krok 40: Funkcja checkPrice uruchamiana przyciskiem

    Kryteria: ,

    R.3.4 Po wciśnięciu przycisku wywoływana jest funkcja zapisana skryptem

    R.5.1 Skrypt napisano w języku uruchamianym po stronie przeglądarki i zawiera on co najmniej jedną instrukcję tego języka zapisaną zgodnie ze składnią

    ok. 3 min
    Polecenie z arkusza

    Napisany w języku wykonywanym po stronie przeglądarki. Uruchamia się po wciśnięciu przycisku na stronie fryzura.html

    Językiem wykonywanym w przeglądarce jest JavaScript. Skrypt stoi w znaczniku <script> na końcu <body> strony fryzura.html - przeglądarka zna już wtedy wszystkie pola.

    • funkcja checkPrice() zbierze całe obliczenie; na razie ma tylko zmienną price z wartością początkową 0,
    • przycisk dostaje atrybut onclick="checkPrice()" (zdarzenie z tabeli arkusza) - kliknięcie wywołuje funkcję (R.3.4, R.5.1).
    Typowe błędy

    onclick="checkPrice" bez nawiasów nie wywoła funkcji - przeglądarka tylko odczyta jej nazwę.

    fryzura.html HTML zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h3>Dziś promocja na strzyżenie włosów</h3>
            <input type="radio" name="length" id="short"> Krótkie<br>
            <input type="radio" name="length" id="medium"> Średnie<br>
            <input type="radio" name="length" id="halflong"> Półdługie<br>
            <input type="radio" name="length" id="long"> Długie<br>
            <button onclick="checkPrice()">Odkryj promocję</button>
            <p id="result"></p>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
        <script>
            function checkPrice() {
                var price = 0;
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  41. Krok 41: Pierwsze pole: sprawdzenie zaznaczenia instrukcją if

    Kryteria:

    R.5.2 Skrypt sprawdza za pomocą instrukcji warunkowej lub wyboru, które pole radio jest zaznaczone

    ok. 3 min
    Polecenie z arkusza

    Podaje cenę strzyżenia w zależności od wyboru dokonanego przez pola radio zgodnie z cennikiem w tabeli

    Właściwość checked pola radio ma wartość true, gdy pole jest zaznaczone. Instrukcja if sprawdza pole „Krótkie” i przy zaznaczonym ustawia cenę z cennika: 25 (R.5.2):

    • document.getElementById('short') - pole o identyfikatorze short,
    • .checked - jego stan,
    • price = 25 - przypisanie, bo cena zależy od jednego wybranego pola (nic się tu nie sumuje).
    Typowe błędy

    .value pola radio bez atrybutu value to zawsze tekst on - o zaznaczeniu mówi wyłącznie checked.

    fryzura.html HTML zmienione: 3 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h3>Dziś promocja na strzyżenie włosów</h3>
            <input type="radio" name="length" id="short"> Krótkie<br>
            <input type="radio" name="length" id="medium"> Średnie<br>
            <input type="radio" name="length" id="halflong"> Półdługie<br>
            <input type="radio" name="length" id="long"> Długie<br>
            <button onclick="checkPrice()">Odkryj promocję</button>
            <p id="result"></p>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
        <script>
            function checkPrice() {
                var price = 0;
                if (document.getElementById('short').checked) {
                    price = 25;
                }
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  42. Krok 42: Pozostałe pola: else if dla każdej długości

    Kryteria:

    R.5.3 Skrypt ustala cenę strzyżenia w zależności od wyboru dokonanego w polach radio zgodnie z tabelą w arkuszu

    ok. 3 min
    Polecenie z arkusza

    Podaje cenę strzyżenia w zależności od wyboru dokonanego przez pola radio zgodnie z cennikiem w tabeli

    Kolejne gałęzie else if z cenami z tabeli arkusza: Średnie 30, Półdługie 40, Długie 50. Tu else if pasuje lepiej niż osobne if: pola radio tworzą jedną grupę, więc zaznaczone jest najwyżej jedno - gdy znajdzie się zaznaczone pole, dalszych nie trzeba sprawdzać (R.5.3).

    Gdy żadne pole nie jest zaznaczone, żadna gałąź się nie wykona i zostaje cena początkowa 0.

    fryzura.html HTML zmienione: 6 linii
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h3>Dziś promocja na strzyżenie włosów</h3>
            <input type="radio" name="length" id="short"> Krótkie<br>
            <input type="radio" name="length" id="medium"> Średnie<br>
            <input type="radio" name="length" id="halflong"> Półdługie<br>
            <input type="radio" name="length" id="long"> Długie<br>
            <button onclick="checkPrice()">Odkryj promocję</button>
            <p id="result"></p>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
        <script>
            function checkPrice() {
                var price = 0;
                if (document.getElementById('short').checked) {
                    price = 25;
                } else if (document.getElementById('medium').checked) {
                    price = 30;
                } else if (document.getElementById('halflong').checked) {
                    price = 40;
                } else if (document.getElementById('long').checked) {
                    price = 50;
                }
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  43. Krok 43: Wynik pod przyciskiem: „Cena strzyżenia: cena”

    Kryteria:

    R.5.4 Skrypt wypisuje wynik pod przyciskiem według wzoru: „Cena strzyżenia: <wartość>”, gdzie <wartość> oznacza cenę ustaloną przez skrypt

    ok. 2 min
    Polecenie z arkusza

    Wyświetla wynik działania pod przyciskiem według wzoru: „Cena strzyżenia: <wartość>”, gdzie <wartość> oznacza cenę strzyżenia dla wskazanej długości włosów

    Ostatnia linia funkcji wpisuje tekst do akapitu result pod przyciskiem: innerHTML (z tabeli arkusza) zastępuje zawartość elementu, a operator + skleja napis 'Cena strzyżenia: ' z liczbą (R.5.4).

    Sprawdzone w Chrome, klikając kolejno każde pole i przycisk: 25, 30, 40, 50 - zgodnie z cennikiem; po kliknięciu „Długie” zaznaczone zostaje tylko to jedno pole. Bez zaznaczenia skrypt wypisuje „Cena strzyżenia: 0”. Kliknij pola i przycisk w podglądzie.

    Typowe błędy

    document.write po załadowaniu strony zamazuje całą stronę wynikiem - wynik ma stanąć pod przyciskiem, więc trzeba wpisać go do elementu.

    fryzura.html HTML zmienione: 1 linia
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h3>Dziś promocja na strzyżenie włosów</h3>
            <input type="radio" name="length" id="short"> Krótkie<br>
            <input type="radio" name="length" id="medium"> Średnie<br>
            <input type="radio" name="length" id="halflong"> Półdługie<br>
            <input type="radio" name="length" id="long"> Długie<br>
            <button onclick="checkPrice()">Odkryj promocję</button>
            <p id="result"></p>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
        <script>
            function checkPrice() {
                var price = 0;
                if (document.getElementById('short').checked) {
                    price = 25;
                } else if (document.getElementById('medium').checked) {
                    price = 30;
                } else if (document.getElementById('halflong').checked) {
                    price = 40;
                } else if (document.getElementById('long').checked) {
                    price = 50;
                }
                document.getElementById('result').innerHTML = 'Cena strzyżenia: ' + price;
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  44. Etap 5: Dobre praktyki (poza kluczem)

    Kroki 44-45 · po tym etapie masz 33 z 33 kryteriów (pkt)

    Krok 44: Prawo ALTER: konto bez DELETE i tak usuwa dane

    ok. 3 min
    Polecenie z arkusza

    Zapytanie 4: nadające prawa tworzenia i modyfikowania struktury tabeli oraz przeglądania danych w tabeli kadra bazy egzamin2 dla użytkownika fryzjer

    Konto fryzjer nie ma prawa DELETE - sprawdzone logowaniem na nie: DELETE FROM kadra WHERE id = 1 kończy się odmową ERROR 1142 (42000) …. Mimo to konto może zniszczyć dane. Prawo ALTER pozwala zmieniać strukturę tabeli, także usuwać kolumny. Polecenie wykonane na koncie fryzjer:

    ALTER TABLE kadra DROP COLUMN stanowisko;
    

    przeszło bez błędu - kolumna stanowisko zniknęła ze wszystkich pięciu wierszy razem z danymi (na zrzucie stan tabeli po poleceniu, tylko id, imie, nazwisko). Wniosek: prawa do struktury (ALTER, DROP) są groźniejsze niż prawa do pojedynczych wierszy i daje się je wyłącznie kontom administracyjnym. Konto, którego używa aplikacja albo pracownik salonu, dostaje tylko prawa do danych (SELECT, ewentualnie INSERT/UPDATE) - zmianą struktury zajmuje się administrator.

    Hasło Fryz12 ma sześć znaków i jest przewidywalne - konto bazy w prawdziwym systemie dostaje długie, losowe hasło. Na egzaminie zapisz zapytania 3 i 4 dokładnie tak, jak każe arkusz - klucz tego nie sprawdza.

    Podgląd strony po tym kroku (fryzura.html)
    Podgląd strony po kroku 44
  45. Krok 45: Cena z przeglądarki to tylko informacja; textContent zamiast innerHTML

    ok. 3 min
    Polecenie z arkusza

    Wyświetla wynik działania pod przyciskiem według wzoru: „Cena strzyżenia: <wartość>”, gdzie <wartość> oznacza cenę strzyżenia dla wskazanej długości włosów

    Skrypt działa w przeglądarce użytkownika, więc użytkownik ma nad nim pełną władzę. Sprawdzone w Chrome: jedna linia wpisana w konsoli narzędzi deweloperskich (F12) - document.getElementById('result').innerHTML = 'Cena strzyżenia: 1' - zmienia wyświetloną cenę długich włosów z 50 na 1 zł. Cena policzona w przeglądarce jest więc tylko podpowiedzią dla klienta. Gdyby strona przyjmowała zamówienia, serwer musiałby policzyć cenę jeszcze raz z własnego cennika i nie ufać liczbie przysłanej z przeglądarki.

    Druga zmiana dotyczy wypisywania: textContent wstawia tekst dosłownie, a innerHTML interpretuje go jako HTML. Dziś skrypt skleja stały napis z liczbą, więc różnicy nie widać - ale gdy do wyniku trafi kiedyś tekst od użytkownika albo z bazy, innerHTML wykona wstawione w nim znaczniki (np. obrazek z atrybutem onerror uruchamiającym skrypt), a textContent pokaże je jako zwykłe znaki. Stara linia zostaje w komentarzu, wyniki dla wszystkich pól są te same. Na egzaminie wystarczy wersja wcześniejsza - klucz tego nie sprawdza.

    fryzura.html HTML zmienione: 2 linie
    <!DOCTYPE html>
    <html lang="pl">
    <head>
        <meta charset="UTF-8">
        <title>Usługi fryzjerskie</title>
        <link rel="stylesheet" href="styl2.css">
    </head>
    <body>
        <section id="left1">
            <h2><a href="index.html">SALON FRYZJERSKI</a></h2>
            <img src="obraz2.jpg" alt="Czesanie">
        </section>
        <section id="right1">
            <h2>MENU</h2>
        </section>
        <section id="right2">
            <ol>
                <li><a href="fryzura.html">Strzyżenie</a>
                    <ul>
                        <li>krótkie</li>
                        <li>średnie</li>
                        <li>półdługie</li>
                        <li>długie</li>
                    </ul>
                </li>
                <li>Czesanie</li>
                <li>Koloryzacja</li>
            </ol>
        </section>
        <section id="left2">
            <h3>Dziś promocja na strzyżenie włosów</h3>
            <input type="radio" name="length" id="short"> Krótkie<br>
            <input type="radio" name="length" id="medium"> Średnie<br>
            <input type="radio" name="length" id="halflong"> Półdługie<br>
            <input type="radio" name="length" id="long"> Długie<br>
            <button onclick="checkPrice()">Odkryj promocję</button>
            <p id="result"></p>
        </section>
        <section id="right3">
            <img src="obraz1.jpg" alt="Fryzjer">
        </section>
        <footer>
            <p>Autor: Bartosz Bryniarski</p>
        </footer>
        <script>
            function checkPrice() {
                var price = 0;
                if (document.getElementById('short').checked) {
                    price = 25;
                } else if (document.getElementById('medium').checked) {
                    price = 30;
                } else if (document.getElementById('halflong').checked) {
                    price = 40;
                } else if (document.getElementById('long').checked) {
                    price = 50;
                }
                // document.getElementById('result').innerHTML = 'Cena strzyżenia: ' + price;
                document.getElementById('result').textContent = 'Cena strzyżenia: ' + price;
            }
        </script>
    </body>
    </html>
    Podgląd strony po tym kroku (fryzura.html)
  46. Etap 6: Oddanie pracy

    Krok 46 · po tym etapie masz 33 z 33 kryteriów (pkt)

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

    ok. 5 min
    Polecenie z arkusza

    Po zakończeniu pracy utwórz plik tekstowy. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowałeś poprawność działania witryny. Nazwij plik przeglądarka.txt i zapisz go w folderze z numerem PESEL. Nagraj płytę z rezultatami pracy.

    W przeglądarka.txt wpisujesz nazwę przeglądarki, w której sprawdzasz strony i skrypt.

    W folderze z numerem PESEL muszą być: egzamin.jpg, fryzura.html, index.html, kw1.png - kw4.png, kwerendy.txt, obraz1.jpg, obraz2.jpg, przeglądarka.txt i styl2.css. Nagraj płytę, sprawdź jej odczyt i opisz ją numerem PESEL - zapakowana w pudełko zostaje na stanowisku razem z arkuszem.

    przeglądarka.txt Tekst nowy plik
    Google Chrome

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

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.

Potwierdzenie

Informacja