INF.03-06-24.06-SGCzerwiec 2024 · 50 kroków · ok. 81 min · 39 kryteriów z klucza
Rozwiązanie krok po kroku: Formularz rejestracji konferencji (Wersja podstawowa)
Formularz rejestracji na konferencję „Nasze Kwiaty”: baza konferencja (uczestnicy i wykłady) i cztery zapytania - warunek na pole TINYINT(1), funkcje agregujące z aliasami (AVG, SUM, COUNT), złączenie JOIN i ALTER TABLE ... DROP COLUMN - potem rozmyta grafika i strona rejestracja.html: baner, blok główny z formularzem w trzech kartach i cztery bloki stopki z filmem, tabelą i odnośnikiem. Karty przełącza JavaScript: kliknięcie „Następna karta” ukrywa bieżącą kartę i pokazuje następną, a „Zatwierdź” porównuje hasła i wita uczestnika 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, getElementById, style.visibility), a na końcu przechodzi do wersji z prawdziwych projektów: jedna funkcja przełączająca karty, nasłuchiwacze zdarzeń i sprawdzenie pól wymaganych przed przejściem dalej.
To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid, flex, JS)” jest drugi sposób rozwiązania tego samego arkusza: strona na siatce CSS, karty formularza w kontenerze flex, stan kart w klasie CSS i skrypt w osobnym pliku z nasłuchiwaczami zdarzeń - obie wersje są zgodne z kluczem.
Baza, zdjęcie i film pochodzą z prawdziwego archiwum pliki6 (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: kliknięcia kart, okienko z komunikatem i napis w konsoli. Podgląd strony jest interaktywny - przyciski „Następna karta” działają tak, jak u ucznia.
Jak liczą się punkty. Klucz ma 39 kryteriów (R.1.1 - R.5.7), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 30 punktów - można stracić 9 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.
Suwak i strzałki obok niego - albo ←→ na klawiaturze - przechodzą krok po kroku; wyjaśnienie, pliki i podgląd zmieniają się razem z krokiem.
Lista „Etap” przenosi od razu do wybranego etapu.
„Rozwiązuję samodzielnie” chowa rozwiązanie kroku - najpierw własna próba, potem odsłonięcie.
„Tryb prezentacji” pokazuje same kroki, bez menu strony - na rzutnik.
Etap 1: Baza danych
Kroki 1-7 · po tym etapie masz 6 z 39 kryteriów (pkt)
Krok 1: Baza danych konferencja
ok. 2 min
Polecenie z arkusza
Utwórz bazę danych o nazwie konferencja, z zestawem polskich znaków (np. utf8_unicode_ci)
Najpierw archiwum pliki6.zip z pulpitu (hasło ^konfErEncja& - daszek na początku, wielkie E dwa razy i ampersand na końcu) rozpakowuje się do folderu nazwanego numerem zdającego. W phpMyAdmin: Nowa, nazwa konferencja, porównywanie utf8_unicode_ci.
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 konferencja, potem Import → baza.sql → Wykonaj. Powstają dwie tabele z obrazu 1: uczestnicy (7 osób) i wyklady (3 wykłady); pole wyklady_id wskazuje wykład, na który zapisał się uczestnik. Pole zaplacono ma typ TINYINT(1): 1 - zapłacił, 0 - jeszcze nie.
Krok 3: Zrzut ekranu import.png
Kryteria:
R.1.1 Wykonano import tabel do bazy danych konferencja 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).
Krok 4: Zapytanie 1: uczestnicy, którzy nie zapłacili
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 imię, nazwisko i koszt konferencji dla uczestników, którzy jeszcze nie zapłacili za konferencję. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko, koszt FROM uczestnicy WHERE zaplacono = FALSE; (lub zaplacono=0) oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 5 rekordów z danymi: Piotr Górski 100, Marcin Szpak 150, Adam Binder 120, Robert Halicki 90, Alicja Warkowska 120
ok. 2 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie imię, nazwisko i koszt konferencji dla uczestników, którzy jeszcze nie zapłacili za konferencję
SELECT imie, nazwisko, koszt - trzy pola,
FROM uczestnicy,
WHERE zaplacono = 0 - „jeszcze nie zapłacił” to wartość 0 w polu TINYINT(1) (klucz uznaje też = FALSE).
Wynik: 5 wierszy - Piotr Górski 100, Marcin Szpak 150, Adam Binder 120, Robert Halicki 90, Alicja Warkowska 120, jak w kluczu. Zapytania zapisuje się w kwerendy.txt, zrzut wyniku jako kw1.jpg.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT imie, nazwisko, koszt FROM uczestnicy WHERE zaplacono = 0;
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: średnia, suma i liczba z aliasami
Kryteria:
R.1.4 Wykonano zapytanie 2 : liczące dla wszystkich uczestników: średni koszt konferencji pod nazwą kolumny „Średni koszt”, sumę kosztów pod nazwą kolumny „Całkowity koszt”, liczbę zapisanych w bazie uczestników pod nazwą kolumny „Liczba uczestników”. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT AVG(koszt) AS "Średni koszt", SUM(koszt) AS "Całkowity koszt", COUNT(*) AS "Liczba uczestników" FROM uczestnicy; oraz wynik działania udokumentowano zrzutem, na którym są widoczne wartości: 117.1429 (dowolne dokładność); 820; 7. Kolumny są podpisane (nadano aliasy)
ok. 2 min
Polecenie z arkusza
Zapytanie 2: liczące dla wszystkich uczestników: średni koszt konferencji z nazwą kolumny (alias) „Średni koszt”, sumę kosztów z nazwą kolumny (alias) „Całkowity koszt”, liczbę zapisanych w bazie uczestników z nazwą kolumny (alias) „Liczba uczestników”
AVG(koszt) AS ... - średnia, SUM(koszt) - suma, COUNT(*) - liczba wierszy,
AS nadaje kolumnie wyniku nazwę (alias); nazwa ze spacją i polskimi literami musi stać w odwrotnych apostrofach - znak z klawisza z tyldą (klucz pokazuje cudzysłowy - MySQL i MariaDB też je przyjmują),
FROM uczestnicy - bez WHERE, bo arkusz każe liczyć „dla wszystkich uczestników”.
Wynik: 117.1429, 820, 7 (820 / 7 = 117,14), z podpisanymi kolumnami - zgodnie z kluczem. Zrzut: kw2.jpg.
Typowe błędy
Alias bez cudzysłowów albo odwrotnych apostrofów (AS Średni koszt) to błąd składni - spacja kończy nazwę.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT imie, nazwisko, koszt FROM uczestnicy WHERE zaplacono = 0;-- Zapytanie 2SELECT AVG(koszt) AS `Średni koszt`, SUM(koszt) AS `Całkowity koszt`, COUNT(*) AS `Liczba uczestników` FROM uczestnicy;
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: wykład i dane uczestników, którzy zapłacili
Kryteria:
R.1.5 Wykonano zapytanie 3 wybierające jedynie nazwę wykładu i przypisane jej nazwiska i e- maile uczestników, dla tych uczestników, którzy zapłacili za konferencję. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, nazwisko, email FROM uczestnicy JOIN wyklady ON wyklady_id = wyklady.id WHERE zaplacono=TRUE; (lub zaplacono=1, możliwe również INNER JOIN lub bez JOIN i porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym są widoczne dokładnie 2 rekordy dla nazwiska Nowak i Rutkowski, jedynie pola nazwa, nazwisko, email
ok. 2 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie nazwę wykładu i przypisane jej nazwiska i e-maile uczestników, dla tych uczestników, którzy zapłacili za konferencję. Należy posłużyć się relacją
SELECT nazwa, nazwisko, email - nazwa wykładu z tabeli wyklady, nazwisko i e-mail z uczestnicy,
FROM uczestnicy JOIN wyklady ON uczestnicy.wyklady_id = wyklady.id - relacja: do uczestnika dołączany jest jego wykład,
WHERE zaplacono = 1 - tylko ci, którzy zapłacili.
Wynik: 2 wiersze - Nowak (Jak dbać o kwiaty doniczkowe?) i Rutkowski (Przegląd kwiatów występujących w Polsce), jak w kluczu. Zrzut: kw3.jpg.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT imie, nazwisko, koszt FROM uczestnicy WHERE zaplacono = 0;-- Zapytanie 2SELECT AVG(koszt) AS `Średni koszt`, SUM(koszt) AS `Całkowity koszt`, COUNT(*) AS `Liczba uczestników` FROM uczestnicy;-- Zapytanie 3SELECT nazwa, nazwisko, email FROM uczestnicy JOIN wyklady ON uczestnicy.wyklady_id = wyklady.id WHERE zaplacono = 1;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: usunięcie kolumny haslo
Kryteria:
R.1.6 Wykonano zapytanie 4 usuwające kolumnę z hasłem uczestnika. W pliku z kwerendami lub na zrzucie istnieje zapis np.: ALTER TABLE uczestnicy DROP COLUMN haslo; (COLUMN jest opcjonalne) oraz wynik działania udokumentowano zrzutem, na którym widoczne jest poprawnie wykonane zapytanie lub struktura tabeli uczestnicy bez kolumny haslo
ok. 2 min
Polecenie z arkusza
Zapytanie 4: usuwające kolumnę z hasłem uczestnika
ALTER TABLE uczestnicy - zmiana struktury tabeli (nie danych),
DROP COLUMN haslo - usunięcie kolumny razem z jej zawartością; słowo COLUMN jest opcjonalne.
Na zrzucie kw4.jpg widać komunikat o wykonaniu zapytania albo strukturę tabeli uczestnicy - osiem kolumn, bez haslo. Zapytanie wykonuje się jako ostatnie: po nim nie ma już czego usuwać, a powtórka kończy się błędem „Can't DROP COLUMN”.
Typowe błędy
DELETE FROM uczestnicy ... usuwa wiersze (uczestników), a nie kolumnę.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT imie, nazwisko, koszt FROM uczestnicy WHERE zaplacono = 0;-- Zapytanie 2SELECT AVG(koszt) AS `Średni koszt`, SUM(koszt) AS `Całkowity koszt`, COUNT(*) AS `Liczba uczestników` FROM uczestnicy;-- Zapytanie 3SELECT nazwa, nazwisko, email FROM uczestnicy JOIN wyklady ON uczestnicy.wyklady_id = wyklady.id WHERE zaplacono = 1;-- Zapytanie 4ALTER TABLE uczestnicy DROP COLUMN haslo;
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-31 · po tym etapie masz 20 z 39 kryteriów (pkt)
Krok 8: tulipany.jpg: rozmycie Gaussa 3,5 px
Kryteria:
R.2.1 Plik tulipany.jpg jest rozmyty w takim stopniu że można rozpoznać kwiaty na obrazie. Czynność rozmycia udokumentowano zrzutem na którym jest widoczne okno filtra rozmycie
ok. 3 min
Polecenie z arkusza
Na grafice tulipany.jpg należy zastosować filtr rozmycia Gaussa. Rozmycie ma być niewielkie, tak aby można było dalej rozpoznać kwiaty na obrazie. Dla grafiki na obrazie 2 zastosowano rozmiar rozmycia 3,5 w obu osiach. Należy wykonać zrzut ekranu potwierdzający zastosowanie filtru i nazwać go rozmycie.png. Na zrzucie ma być widoczne okno dialogowe służące do podania parametrów rozmycia.
W GIMP-ie: Filtry → Rozmycie → Rozmycie Gaussa, rozmiar X i Y po 3,5 (łańcuch między nimi zamknięty, wtedy obie osie zmieniają się razem). Kiedy okno filtru jest jeszcze otwarte, wykonuje się zrzut ekranu i zapisuje go jako rozmycie.png - na zrzucie musi być widoczne to okno z parametrami. Potem OK i Plik → Nadpisz tulipany.jpg (ta nazwa trafi do arkusza stylów). Grafika ma 1343×500 px - jej wysokość to dokładnie wysokość bloku głównego. Podgląd pokazuje ten sam wycinek przed rozmyciem i po nim; tulipany nadal są rozpoznawalne.
Typowe błędy
Zrzut zrobiony po zamknięciu okna filtru nie dokumentuje parametrów - klucz wymaga widocznego okna rozmycia.
Podgląd strony po tym kroku
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 nie ma PHP, więc wystarczy rozszerzenie .html i można ją otworzyć prosto z dysku.
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.
R.3.6 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 - bez atrybutów style w HTML-u.
Typowe błędy
Klucz odbiera R.3.6 także wtedy, gdy choć jeden selektor nie trafia w blok (np. kropka zamiast # przy identyfikatorze).
Krok 14: Bloki: baner, blok główny, cztery bloki stopki
Kryteria:
R.2.4 Układ strony zdefiniowano dzieląc ją na bloki: banera, główny oraz cztery bloki stopki. 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 baner, poniżej blok główny, na dole cztery bloki stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2
Baner to <header>, blok główny - <main>, a każdy z czterech bloków stopki to osobny <footer> (klucz R.2.4: „stopki - footer”). Znacznik <footer> może wystąpić na stronie kilka razy - w odróżnieniu od <main>, który jest tylko jeden. Wszystkie cztery stopki mają ten sam wygląd, więc w arkuszu stylów obsłuży je jeden selektor footer; identyfikatory nie są potrzebne.
R.2.10 Fraza „Nasze Kwiaty” jest zapisana w znaczniku semantycznym <em>
ok. 1 min
Polecenie z arkusza
Zawartość banera: nagłówek pierwszego stopnia o treści „Formularz rejestracyjny konferencji Nasze Kwiaty”. Fraza „Nasze Kwiaty” jest zapisana w znaczniku semantycznym, który jest pochylony i oznacza tekst uwypuklony
<h1>, a w nim <em> - znacznik uwypuklenia (ang. emphasis), który przeglądarka pisze kursywą. <i> daje tę samą kursywę, ale nie niesie znaczenia.
Typowe błędy
<i>Nasze Kwiaty</i> wygląda tak samo, ale klucz (R.2.10) wymaga <em>.
R.2.6 W bloku głównym umieszczono formularz, zastosowano znacznik <form>
ok. 1 min
Polecenie z arkusza
Zawartość bloku głównego: formularz złożony z trzech bloków
Znacznik <form> obejmuje wszystkie trzy karty. Arkusz nie każe nigdzie wysyłać danych (obsługuje je skrypt), więc formularz nie ma atrybutów action ani method.
Krok 17: Blok 1: karta z nagłówkiem „Dane osobowe”
ok. 1 min
Polecenie z arkusza
Blok 1: Nagłówek drugiego stopnia o treści „Dane osobowe”
Każda karta formularza to <div> z klasą card (wspólny wygląd wszystkich trzech) i własnym identyfikatorem - po nim skrypt będzie ją ukrywał i pokazywał. Pierwsza karta: id="personal", w środku <h2>.
Pole edycyjne z podpowiedzią „Wpisz imię...”, pole jest wymagane
Podpowiedź to atrybut placeholder - szary napis znika, gdy zaczyna się pisać. Pole wymagane to atrybut required. id="firstName" przyda się w skrypcie, który pobierze imię do powitania w konsoli.
Przycisk o treści „Następna karta”, którego kliknięcie powoduje wywołanie funkcji skryptu
Ważny szczegół: type="button". Przycisk wewnątrz <form> bez tego atrybutu ma typ submit - kliknięcie wysłałoby formularz, strona przeładowałaby się i od razu wróciła do pierwszej karty. Funkcję skryptu przycisk dostanie w części o JavaScripcie.
Typowe błędy
<button> bez type="button" w formularzu przeładowuje stronę - karta 2 mignie i zniknie.
Blok 2: Nagłówek drugiego stopnia o treści „Dane kontaktowe”. Pole edycyjne z podpowiedzią „Twój e-mail...”, pole typu dedykowanego do wpisania adresu e-mail
Druga karta (id="contact"). Typ dedykowany adresowi e-mail to type="email" - przeglądarka sprawdza, czy w polu jest małpa i domena, a telefon pokazuje klawiaturę z „@”.
R.3.2 W bloku głównym zdefiniowano trzy bloki (mogą być widoczne wszystkie trzy, lub tylko jeden, lub żaden)
ok. 1 min
Polecenie z arkusza
Blok 3: Nagłówek drugiego stopnia o treści „Hasło do logowania”. Pole edycyjne z podpowiedzią „Podaj hasło”, pole ukrywa wpisywane hasło
Trzecia karta (id="login"). Pole ukrywające znaki to type="password" - zamiast liter widać kropki, jak na obrazie 4. W bloku głównym są już trzy bloki formularza (R.3.2).
R.3.3 Przynajmniej jedna kontrolka ma podpowiedź (placeholder), kontrolki do wpisania imienia i nazwiska są wymagane (required), kontrolka do wpisania maila jest typu email, do wpisania telefonu typu tel i obie do wpisania hasła typu password
ok. 1 min
Polecenie z arkusza
Pole edycyjne z podpowiedzią „Powtórz hasło”, pole ukrywa wpisywane hasło
Drugie pole password z identyfikatorem repeatPassword. Z tym krokiem są spełnione wszystkie warunki R.3.3: podpowiedzi, pola wymagane, typy email, tel i dwa password.
R.2.7 Na stronie zdefiniowano 6 pól edycyjnych i trzy przyciski
ok. 1 min
Polecenie z arkusza
Przycisk o treści „Zatwierdź”, którego kliknięcie powoduje wywołanie funkcji skryptu
Trzeci przycisk. Na stronie jest sześć pól edycyjnych i trzy przyciski - komplet z R.2.7. W podglądzie wszystkie trzy karty stoją jeszcze jedna pod drugą; ułoży je arkusz stylów.
R.2.8 W pierwszym bloku stopki umieszczono video motyl.mp4 z widocznymi kontrolkami
ok. 1 min
Polecenie z arkusza
Zawartość pierwszego bloku stopki: Film motyl.mp4, z kontrolkami umożliwiającymi sterowanie filmem. W przypadku problemów z odtworzeniem filmu pojawia się tekst: „Przeglądarka nie obsługuje tego formatu”
Znacznik <video> z atrybutem controls - bez niego film nie ma przycisku odtwarzania, paska postępu ani głośności. Tekst między <video> a </video> wyświetli tylko przeglądarka, która nie potrafi odtworzyć filmu.
Typowe błędy
<video src="motyl.mp4"> bez controls - film stoi jak obrazek i nie da się go uruchomić (R.2.8 wymaga widocznych kontrolek).
R.2.5 W bloku banera zapisano nagłówek h1 "Formularz rejestracyjny konferencji Nasze Kwiaty" , w bloku głównym przynajmniej jeden h2 z: "Dane osobowe", "Dane kontaktowe" lub "Hasło do logowania" , w drugim bloku stopki h3 "Plan konferencji" oraz paragrafy w trzecim i czwartym bloku stopki
ok. 1 min
Polecenie z arkusza
Zawartość czwartego bloku stopki: paragraf o treści: „Formularz wykonał: ”, dalej wstawiony numer zdającego.
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 i akapity z R.2.5: <h1> w banerze, <h2> w kartach, <h3> w drugiej stopce i akapity w trzeciej i czwartej.
Dla bloku głównego: tło stanowi obraz tulipany.jpg, wysokość 500 px
background-image: url("tulipany.jpg") - ścieżka liczona od pliku CSS, a grafika leży w tym samym folderze. Obraz ma 500 px wysokości, czyli tyle, co blok; w szerokości jest węższy niż okno, więc tło powtarza się w poziomie - stąd widoczny szew po prawej stronie obrazu 2.
Wspólne dla wszystkich bloków stopki: kolor tła #C2185B, biały kolor czcionki, szerokość 25%, wysokość 240 px
Jeden selektor footer łapie wszystkie cztery stopki. Na razie stoją jedna pod drugą, każda na ćwierć szerokości - obok siebie ustawi je reguła układu na końcu tej części.
Krok 36: Karty formularza: obok siebie, tło, wymiary, marginesy
Kryteria:
R.4.8 Ustawiono styl dla przynajmniej jednego bloku w formularzu: kolor tła #FCE4EC, szerokość 25%, wysokość 300px, marginesy zewnętrzne 25px, wewnętrzne 16px
ok. 2 min
Polecenie z arkusza
Wspólne dla trzech bloków w formularzu: bloki umieszczone obok siebie, kolor tła #FCE4EC, szerokość 25%, wysokość 300 px, marginesy zewnętrzne 25 px, wewnętrzne 16 px
Klasa .card - te same cechy dla trzech kart. „Obok siebie” to float: left: każda karta przesuwa się do lewej, a następna staje przy niej. Karty mieszczą się w bloku głównym (300 px wysokości plus marginesy i dopełnienie to 382 px, blok ma 500 px), więc opływanie nie wyjdzie poza <main>. Uwaga na szerokość okna: każda karta to 25% plus 82 px stałych marginesów i dopełnienia, więc trzy karty mieszczą się w jednym wierszu dopiero od ok. 1000 px szerokości okna - w węższym oknie (także w wąskim podglądzie) trzecia karta spada niżej i wystaje z bloku głównego. Na ekranie stanowiska egzaminacyjnego układ jest taki jak na obrazie 2.
R.4.9 Ustawiono dla drugiego i trzeciego bloku cechę visibility: hidden;
ok. 2 min
Polecenie z arkusza
Dodatkowo pierwszy blok jest widoczny, pozostałe dwa są ukryte. Należy zastosować właściwość CSS, która jedynie ukrywa blok, a nie usuwa go
Właściwość, która „jedynie ukrywa”, to visibility: hidden - blok jest niewidoczny, ale zajmuje swoje miejsce. Dlatego na obrazach 3 i 4 druga karta pojawia się na środku, a trzecia po prawej: puste miejsca po ukrytych kartach zostają. display: none usunąłby blok z układu i karty pojawiałyby się zawsze po lewej - arkusz wyklucza tę właściwość.
Typowe błędy
display: none zamiast visibility: hidden - klucz (R.4.9) wymaga wprost visibility: hidden.
Dla wszystkich pól edycyjnych oprócz przycisków: szerokość 80%, wysokość 30 px, marginesy zewnętrzne 10 px
Przyciski są znacznikami <button>, a pola - <input>, więc sam selektor input spełnia „oprócz przycisków”. Gdyby przyciski były zapisane jako <input type="button">, trzeba by zawęzić selektor, np. input:not([type="button"]). Pole na 80% szerokości karty zajmuje cały wiersz, więc pola stoją jedno pod drugim.
R.4.2 Ustawiono kolor tła #C2185B dla bloków banera, wszystkich bloków stopki i przycisków oraz blok główny ma tło w postaci obrazu tulipany.jpg (formatowanie przycisku za pomocą id jest błędem)
R.4.3 Ustawiono biały kolor czcionki dla banera, wszystkich bloków stopki, odnośnika i przycisków
R.4.7 Ustawiono marginesy wewnętrzne (padding) 15px dla banera, 20px dla przycisków, górny 20px dla selektora p oraz zewnętrzne (margin) 10px dla przynajmniej jednego pola edycyjnego, górny 50px i lewy 60% dla przycisków
R.4.10 Ustawiono brak obramowania dla przycisków
ok. 2 min
Polecenie z arkusza
Dla wszystkich przycisków: kolor tła #c2185b, biały kolor czcionki, margines zewnętrzny górny 50 px, margines zewnętrzny lewy 60%, marginesy wewnętrzne 20 px, brak obramowania
Selektor button łapie trzy przyciski (klucz przy R.4.2: „formatowanie przycisku za pomocą id jest błędem”). margin-left: 60% liczy się od szerokości karty - przycisk odsuwa się w prawo, jak na obrazie 2. border: none zdejmuje domyślną ramkę. Ta reguła zamyka trzy kryteria: kolory tła (baner, stopki, przyciski i tło z obrazem w bloku głównym - R.4.2), biel czcionki (R.4.3) i komplet marginesów (R.4.7).
R.4.4 Ustawiono wysokość bloku głównego 500px, wszystkich stopek 240px, przynajmniej jednego pola edycyjnego 30px oraz video 100%
R.4.5 Ustawiono szerokość wszystkich bloków stopki 25% (width lub grid-template-columns lub flex), przynajmniej jednego pola edycyjnego 80% oraz video 100%
ok. 1 min
Polecenie z arkusza
Dla video: szerokość i wysokość 100%
Film wypełnia pierwszą stopkę (25% szerokości, 240 px wysokości); przeglądarka zachowuje proporcje filmu (16:9), więc nad filmem i pod nim zostają pasy - przezroczyste, widać przez nie tło stopki. Ta reguła zamyka kryteria wysokości (blok główny, stopki, pole, film - R.4.4) i szerokości (stopki, pole, film - R.4.5).
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z obrazem 2 w arkuszu egzaminacyjnym, nie należy brać pod uwagę zawartości bloku głównego (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 baner, poniżej blok główny, na dole cztery bloki stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2
Baner i blok główny stoją jeden pod drugim same, jako elementy blokowe. Cztery stopki mają po 25%, więc z float: left układają się w jednym wierszu na całą szerokość (4 · 25% = 100%; dlatego stopki nie mają marginesów ani obramowania - każdy dodatkowy piksel zepchnąłby czwartą stopkę do nowego wiersza). Blok główny ma stałą wysokość 500 px, więc pływające karty z jego środka nie wpływają na stopki.
Typowe błędy
margin albo border dla stopek przy szerokości 25% - czwarty blok spada do drugiego wiersza.
Kroki 44-47 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 44: Funkcja dla przycisku z karty 1
Kryteria: , ,
R.5.1 Skrypt zapisano w języku JavaScript i zawiera on przynajmniej jedną instrukcję zapisaną zgodnie ze składnią
R.5.2 Po wciśnięciu przycisku w pierwszym bloku, jest ukrywany blok 1, blok 2 staje się widoczny
R.3.5 Dla dowolnego przycisku zdefiniowano zdarzenie związane z jego kliknięciem , które odwołuje się do funkcji w skrypcie (atrybut onClick lub słuchacz zdarzenia click lub właściwość onclick obiektu DOM)
ok. 3 min
Polecenie z arkusza
Działanie funkcji dla kliknięcia przycisku z pierwszego bloku: ukrywany jest blok 1, blok 2 staje się widoczny
Skrypt w znaczniku <script> na końcu <body> - wtedy wszystkie karty już istnieją, gdy przeglądarka czyta kod. Funkcja showContact odnajduje kartę po identyfikatorze (getElementById) i zmienia jej styl: style.visibility = "hidden" ukrywa kartę 1, "visible" pokazuje kartę 2. Przycisk z karty 1 dostaje atrybut onclick="showContact()" - kliknięcie wywołuje funkcję. W podglądzie można już kliknąć „Następna karta”: karta 2 pojawia się na środku, jak na obrazie 3.
R.5.3 Po wciśnięciu przycisku w drugim bloku, jest ukrywany blok 2, blok 3 staje się widoczny
ok. 2 min
Polecenie z arkusza
Działanie funkcji dla kliknięcia przycisku z drugiego bloku: ukrywany jest blok 2, blok 3 staje się widoczny
Ta sama budowa, inne identyfikatory: chowa się contact, pojawia login. Przycisk z karty 2 wywołuje showLogin(). Trzecia karta pojawia się po prawej - jak na obrazie 4.
R.5.5 Po wciśnięciu przycisku w trzecim oknie, w przypadku, gdy wpisane do pól edycyjnych hasła nie są identyczne, wyświetlane jest okienko popup z komunikatem „Podane hasła różnią się”, w przeciwnym wypadku okienko nie jest wyświetlane
ok. 3 min
Polecenie z arkusza
Działanie funkcji dla kliknięcia przycisku z trzeciego bloku: w przypadku, gdy wpisane do pól edycyjnych hasła nie są identyczne wyświetlane jest okienko popup z komunikatem „Podane hasła różnią się”
Wartość pola to właściwość value elementu znalezionego przez getElementById. Dwie zmienne, password i repeatedPassword, i porównanie operatorem !=; gdy hasła są różne, alert pokazuje okienko z komunikatem (obraz 5). Przy zgodnych hasłach okienko się nie pojawia - tego też wymaga klucz.
R.5.4 Oba hasła oraz imię i nazwisko pobrano za pomocą odpowiedniej funkcji obiektu document (np. getElementById)
R.5.6 Po wciśnięciu przycisku w trzecim oknie, wyświetlany jest w konsoli komunikat o treści: „Witaj <imie> <nazwisko>”, gdzie wartości w nawiasach są pobrane z pól edycyjnych
R.5.7 Zastosowano znaczące nazewnictwo dla wszystkich zmiennych i funkcji w języku polskim lub angielskim. Nazwy odzwierciedlają cel zastosowania
ok. 2 min
Polecenie z arkusza
Imię i nazwisko wpisane w pierwszym bloku są pobrane i wyświetlone w konsoli jako napis o treści „Witaj <imie><nazwisko>”, gdzie wartości w nawiasach są pobrane z pól edycyjnych
Pola z karty 1 są tylko ukryte, nie usunięte - ich wartości nadal da się odczytać. Napis skleja operator + (spacje w cudzysłowach), a console.log wypisuje go w konsoli narzędzi deweloperskich (F12, zakładka Console), jak na obrazie 6: „Witaj Alicja Kowalska”. Arkusz nie uzależnia powitania od haseł, więc wypisuje się zawsze. Nazwy funkcji i zmiennych mówią, co robią i co przechowują - kryterium R.5.7.
Kroki 48-49 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 48: Jedna funkcja kart, nasłuchiwacze i sprawdzenie pól
ok. 4 min
Polecenie z arkusza
Przycisk o treści „Następna karta”, którego kliknięcie powoduje wywołanie funkcji skryptu
Wersja z egzaminu sprawdzona w prawdziwej przeglądarce: z pustymi polami imienia i nazwiska da się przejść przez wszystkie karty, a konsola wita uczestnika napisem „Witaj” i dwiema spacjami. Atrybut required nic tu nie daje - przeglądarka sprawdza pola wymagane dopiero przy wysyłaniu formularza, a przyciski type="button" formularza nie wysyłają. Poprawki: jedna funkcja showCard(currentId, nextId) zamiast dwóch prawie identycznych; przed przejściem dalej reportValidity() sprawdza każde pole bieżącej karty i pokazuje dymek przy pustym polu wymaganym albo błędnym adresie e-mail (sprawdzone: „zly-adres” zatrzymuje kartę 2). Kliknięcia obsługują addEventListener w skrypcie, a przyciski mają tylko identyfikatory - HTML opisuje treść, a zachowanie siedzi w jednym miejscu. Stare funkcje zostają w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - klucz uznaje oba sposoby obsługi zdarzeń (R.3.5).
rejestracja.htmlHTMLzmienione: 28 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Rejestracja</title> <linkrel="stylesheet"href="styl.css"></head><body> <header> <h1>Formularz rejestracyjny konferencji <em>Nasze Kwiaty</em></h1> </header> <main> <form> <divclass="card"id="personal"> <h2>Dane osobowe</h2> <inputtype="text"id="firstName"placeholder="Wpisz imię..."required> <inputtype="text"id="lastName"placeholder="Wpisz nazwisko..."required> <buttontype="button"id="toContact">Następna karta</button> </div> <divclass="card"id="contact"> <h2>Dane kontaktowe</h2> <inputtype="email"id="email"placeholder="Twój e-mail..."> <inputtype="tel"id="phone"placeholder="Twój numer telefonu..."> <buttontype="button"id="toLogin">Następna karta</button> </div> <divclass="card"id="login"> <h2>Hasło do logowania</h2> <inputtype="password"id="password"placeholder="Podaj hasło"> <inputtype="password"id="repeatPassword"placeholder="Powtórz hasło"> <buttontype="button"id="confirm">Zatwierdź</button> </div> </form> </main> <footer> <videosrc="motyl.mp4"controls>Przeglądarka nie obsługuje tego formatu</video> </footer> <footer> <h3>Plan konferencji</h3> <table> <tr> <td>9:00 - 12:00</td> <td>Pielęgnacja roślin</td> </tr> <tr> <td>13:00 - 15:00</td> <td>Targi kwiatowe</td> </tr> </table> </footer> <footer> <p><ahref="https://kwiaty.pl/">Internetowa kwiaciarnia</a></p> </footer> <footer> <p>Formularz wykonał: Bartosz Bryniarski</p> </footer> <script>function showCard(currentId, nextId) {let current = document.getElementById(currentId);// pola wymagane z bieżącej karty muszą być wypełnione, zanim pokaże się następnafor (let field of current.querySelectorAll("input")) {if (!field.reportValidity()) {return; } } current.style.visibility = "hidden";document.getElementById(nextId).style.visibility = "visible"; }function confirmRegistration() {let password = document.getElementById("password").value;let repeatedPassword = document.getElementById("repeatPassword").value;if (password != repeatedPassword) { alert("Podane hasła różnią się"); }let firstName = document.getElementById("firstName").value;let lastName = document.getElementById("lastName").value; console.log("Witaj " + firstName + " " + lastName); }document.getElementById("toContact").addEventListener("click", function () { showCard("personal", "contact"); });document.getElementById("toLogin").addEventListener("click", function () { showCard("contact", "login"); });document.getElementById("confirm").addEventListener("click", confirmRegistration);/* Wersja z egzaminu (onclick w HTML-u, dwie prawie identyczne funkcje): function showContact() { document.getElementById("personal").style.visibility = "hidden"; document.getElementById("contact").style.visibility = "visible"; } function showLogin() { document.getElementById("contact").style.visibility = "hidden"; document.getElementById("login").style.visibility = "visible"; } */ </script></body></html>
Podgląd strony po tym kroku (rejestracja.html)
Krok 49: Zatwierdzenie tylko przy zgodnych hasłach
ok. 3 min
Polecenie z arkusza
W przypadku, gdy wpisane do pól edycyjnych hasła nie są identyczne wyświetlane jest okienko popup z komunikatem „Podane hasła różnią się”
W wersji z egzaminu powitanie pojawia się w konsoli także wtedy, gdy hasła się różnią - arkusz opisuje oba działania niezależnie i tak też je ocenia klucz. W prawdziwej rejestracji różne hasła zatrzymują proces: po komunikacie return kończy funkcję. Dochodzi też najprostszy warunek siły hasła (password.length < 8). Sprawdzone w przeglądarce: „abc” i „abcd” - tylko komunikat o różnych hasłach, „abc” dwa razy - komunikat o długości, „tulipan2024” dwa razy - powitanie w konsoli. Na egzaminie wystarczy wersja wcześniejsza - powitanie przy różnych hasłach jest zgodne z arkuszem.
rejestracja.htmlHTMLzmienione: 5 linii
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Rejestracja</title> <linkrel="stylesheet"href="styl.css"></head><body> <header> <h1>Formularz rejestracyjny konferencji <em>Nasze Kwiaty</em></h1> </header> <main> <form> <divclass="card"id="personal"> <h2>Dane osobowe</h2> <inputtype="text"id="firstName"placeholder="Wpisz imię..."required> <inputtype="text"id="lastName"placeholder="Wpisz nazwisko..."required> <buttontype="button"id="toContact">Następna karta</button> </div> <divclass="card"id="contact"> <h2>Dane kontaktowe</h2> <inputtype="email"id="email"placeholder="Twój e-mail..."> <inputtype="tel"id="phone"placeholder="Twój numer telefonu..."> <buttontype="button"id="toLogin">Następna karta</button> </div> <divclass="card"id="login"> <h2>Hasło do logowania</h2> <inputtype="password"id="password"placeholder="Podaj hasło"> <inputtype="password"id="repeatPassword"placeholder="Powtórz hasło"> <buttontype="button"id="confirm">Zatwierdź</button> </div> </form> </main> <footer> <videosrc="motyl.mp4"controls>Przeglądarka nie obsługuje tego formatu</video> </footer> <footer> <h3>Plan konferencji</h3> <table> <tr> <td>9:00 - 12:00</td> <td>Pielęgnacja roślin</td> </tr> <tr> <td>13:00 - 15:00</td> <td>Targi kwiatowe</td> </tr> </table> </footer> <footer> <p><ahref="https://kwiaty.pl/">Internetowa kwiaciarnia</a></p> </footer> <footer> <p>Formularz wykonał: Bartosz Bryniarski</p> </footer> <script>function showCard(currentId, nextId) {let current = document.getElementById(currentId);// pola wymagane z bieżącej karty muszą być wypełnione, zanim pokaże się następnafor (let field of current.querySelectorAll("input")) {if (!field.reportValidity()) {return; } } current.style.visibility = "hidden";document.getElementById(nextId).style.visibility = "visible"; }function confirmRegistration() {let password = document.getElementById("password").value;let repeatedPassword = document.getElementById("repeatPassword").value;if (password != repeatedPassword) { alert("Podane hasła różnią się");return; // przy różnych hasłach rejestracja się nie kończy }if (password.length < 8) { alert("Hasło musi mieć co najmniej 8 znaków");return; }let firstName = document.getElementById("firstName").value;let lastName = document.getElementById("lastName").value; console.log("Witaj " + firstName + " " + lastName); }document.getElementById("toContact").addEventListener("click", function () { showCard("personal", "contact"); });document.getElementById("toLogin").addEventListener("click", function () { showCard("contact", "login"); });document.getElementById("confirm").addEventListener("click", confirmRegistration);/* Wersja z egzaminu (onclick w HTML-u, dwie prawie identyczne funkcje): function showContact() { document.getElementById("personal").style.visibility = "hidden"; document.getElementById("contact").style.visibility = "visible"; } function showLogin() { document.getElementById("contact").style.visibility = "hidden"; document.getElementById("login").style.visibility = "visible"; } */ </script></body></html>
Podgląd strony po tym kroku (rejestracja.html)
Etap 6: Oddanie pracy
Krok 50 · po tym etapie masz 39 z 39 kryteriów (pkt)
Krok 50: 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 (film motyl.mp4 w formacie MP4 odtwarzają wszystkie popularne przeglądarki).
W folderze z numerem zdającego: import.png, kw1.jpg - kw4.jpg, kwerendy.txt, motyl.mp4, przeglądarka.txt, rejestracja.html, rozmycie.png, styl.css, tulipany.jpg (rozmyty). Płytę trzeba nagrać, sprawdzić jej odczyt i opisać numerem zdającego.
Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.
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: Bartosz Bryniarski. 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.