INF.03-08-24.06-SGCzerwiec 2024 · 54 kroki · ok. 90 min · 43 kryteria z klucza
Rozwiązanie krok po kroku: Rejestracja użytkownika sklepu (Wersja podstawowa)
Formularz rejestracji nowego użytkownika sklepu: baza klienci (osoby, ich adresy i telefony - jedna osoba może mieć kilka adresów i kilka numerów) i cztery zapytania - warunek na datę urodzenia, DISTINCT z sortowaniem, złączenie JOIN i ALTER TABLE ... ADD COLUMN ... AFTER - potem plakietka wycięta z grafiki z przezroczystym tłem i strona rejestracja.html: blok boczny z promocjami, baner, blok główny z trzema zakładkami formularza, pasek postępu i stopka. JavaScript przełącza zakładki, wydłuża pasek postępu po opuszczeniu każdego pola i wypisuje wpisane dane w konsoli.
Kroki idą zdanie po zdaniu za treścią arkusza - przy każdym jest polecenie z arkusza, a kod pokazuje dokładnie te linie, które je spełniają. Skrypt powstaje najpierw najprościej (atrybuty onclick i onblur, getElementById, style.display), a na końcu przechodzi do wersji z prawdziwych projektów: pasek liczony z wypełnionych pól zamiast z kliknięć, nasłuchiwacze zdarzeń i zgoda RODO sprawdzana przed zatwierdzeniem.
To jest wersja podstawowa. W zakładce „Nowoczesny kod (grid)” jest drugi sposób rozwiązania tego samego arkusza: bloki na siatce CSS w kolejności treści, kolory w zmiennych, zakładki przełączane klasą CSS i skrypt bez atrybutów w HTML-u - obie wersje są zgodne z kluczem.
Baza i grafika pochodzą z prawdziwego archiwum pliki8 (załącznik do arkusza, hasło w treści zadania). Zrzuty wyników zapytań są odtworzone z tej bazy - na egzaminie robi się je samemu, z całego ekranu. Skrypt został sprawdzony w prawdziwej przeglądarce: przełączanie zakładek, szerokości paska po kolejnych polach i napis w konsoli. Podgląd strony jest interaktywny - zakładki i pasek postępu działają tak, jak u ucznia.
Jak liczą się punkty. Klucz ma 43 kryteria (R.1.1 - R.5.9), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 33 punkty - można stracić 10 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.
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 43 kryteriów (pkt)
Krok 1: Baza danych klienci
ok. 2 min
Polecenie z arkusza
Utwórz bazę danych o nazwie klienci, z zestawem polskich znaków (np. utf8_unicode_ci)
Najpierw archiwum pliki8.zip z pulpitu (hasło _Rejestr@cja_ - podkreślenia na obu końcach i małpa zamiast „a”) rozpakowuje się do folderu nazwanego numerem zdającego. W phpMyAdmin: Nowa, nazwa klienci, porównywanie utf8_unicode_ci.
Krok 2: Import tabel z pliku baza.sql
ok. 2 min
Polecenie z arkusza
Do bazy zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum
Zaznaczona baza klienci, potem Import → baza.sql → Wykonaj. Powstają trzy tabele z obrazu 1: osoby (7 osób z datą urodzenia dataUr), adresy i telefony - obie z polem Osoby_id, które wskazuje właściciela. Jedna osoba może mieć kilka adresów i kilka telefonów, dlatego są to osobne tabele.
Krok 3: Zrzut ekranu import.png
Kryteria:
R.1.1 Wykonano import tabel do bazy danych klienci czynność udokumentowano plikiem o nazwie import w formacie PNG
ok. 2 min
Polecenie z arkusza
Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie PNG i nazwij import. Nie kadruj zrzutu. Powinien on obejmować cały ekran monitora, z widocznym paskiem zadań. Na zrzucie powinny być widoczne elementy wskazujące na poprawnie wykonany import tabel.
Print Screen, wklejenie do edytora grafiki i zapis jako import.png. Zrzuty zapytań idą później do JPEG.
Typowe błędy
Wykadrowany zrzut albo zrzut bez paska zadań nie jest oceniany (uwaga w kluczu przy R.1).
Krok 4: Zapytanie 1: osoby urodzone po 2000 roku
Kryteria: ,
R.1.2 Zapisano plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Wykonano zapytanie 1 wybierające jedynie imiona i nazwiska osób urodzonych po 2000 roku. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko FROM osoby WHERE dataUr >="2001-01-01"; (lub dataUr > "2000-12-31") oraz wynik działania udokumentowano zrzutem, na którym są widoczne jedynie dane: Anna Kowalewska, Ewa Kowalska, Andrzej Nowak
ok. 2 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie imiona i nazwiska osób urodzonych po 2000 roku
SELECT imie, nazwisko - dwa pola,
FROM osoby,
WHERE dataUr > '2000-12-31' - „po 2000 roku” znaczy od 1 stycznia 2001; datę zapisuje się jako tekst w formacie RRRR-MM-DD, a baza porównuje ją jak datę. Równoważne są dataUr >= '2001-01-01' i YEAR(dataUr) > 2000 (sprawdzone - ten sam wynik).
Wynik: Anna Kowalewska, Ewa Kowalska, Andrzej Nowak - jak w kluczu. Zapytania zapisuje się w kwerendy.txt, zrzut jako kw1.jpg.
Typowe błędy
dataUr > '2000' albo dataUr >= '2000-01-01' łapie też osoby urodzone w 2000 roku, a te nie są urodzone „po 2000 roku”.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT imie, nazwisko FROM osoby WHERE dataUr > '2000-12-31';
Podgląd strony po tym kroku
Krok 5: Zapytanie 2: miasta bez powtórzeń, alfabetycznie
Kryteria:
R.1.4 Wykonano zapytanie 2 wybierające nazwy miast, z których pochodzą klienci posortowane alfabetycznie rosnąco. Nazwy miast nie mogą się powtarzać. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT DISTINCT miasto FROM `adresy` ORDER BY miasto; oraz wynik działania udokumentowano zrzutem, na którym są widoczne dokładnie 4 rekordy w kolejności: Kraków, Poznań, Warszawa, Wrocław
ok. 2 min
Polecenie z arkusza
Zapytanie 2: wybierające nazwy miast, z których pochodzą klienci posortowane alfabetycznie rosnąco. Nazwy miast nie mogą się powtarzać
SELECT DISTINCT miasto - DISTINCT usuwa powtórzenia: Poznań i Warszawa występują w adresach po dwa razy, a w wyniku raz,
FROM adresy,
ORDER BY miasto - sortowanie rosnąco (ASC jest domyślne).
Wynik: 4 wiersze - Kraków, Poznań, Warszawa, Wrocław, w kolejności z klucza. Zrzut: kw2.jpg.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT imie, nazwisko FROM osoby WHERE dataUr > '2000-12-31';-- Zapytanie 2SELECT DISTINCT miasto FROM adresy ORDER BY miasto;
Podgląd strony po tym kroku
Krok 6: Zapytanie 3: osoby z numerami telefonów
Kryteria:
R.1.5 Wykonano zapytanie 3 wybierające jedynie imiona i nazwiska osób oraz odpowiadające im numery telefonów. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwisko, telefony.numer FROM osoby JOIN telefony ON osoby.id = telefony.Osoby_id; (możliwe również INNER JOIN lub porównanie kluczy po WHERE) oraz wynik działania udokumentowano zrzutem, na którym jest widocznych dokładnie 9 rekordów z czego dla Anny Kowalewskiej i Anny Nowak są dwa numery telefonu
ok. 2 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie imiona i nazwiska osób oraz odpowiadające im numery telefonów. Należy posłużyć się relacją
SELECT imie, nazwisko, telefony.numer - przy numer nazwa tabeli: kolumna o tej nazwie jest też w tabeli adresy, więc dobrze ją doprecyzować,
FROM osoby JOIN telefony ON osoby.id = telefony.Osoby_id - relacja: do osoby dołączany jest każdy jej telefon.
Wynik: 9 wierszy - tyle, ile telefonów; Anna Kowalewska i Anna Nowak występują dwa razy, bo mają po dwa numery (zgodnie z kluczem). Zrzut: kw3.jpg.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT imie, nazwisko FROM osoby WHERE dataUr > '2000-12-31';-- Zapytanie 2SELECT DISTINCT miasto FROM adresy ORDER BY miasto;-- Zapytanie 3SELECT imie, nazwisko, telefony.numer FROM osoby JOIN telefony ON osoby.id = telefony.Osoby_id;
Podgląd strony po tym kroku
Krok 7: Zapytanie 4: nowa kolumna numerMieszkania
Kryteria:
R.1.6 Wykonano zapytanie 4 dodające do tabeli adresy kolumnę numerMieszkania typu całkowitego, po kolumnie numer. W pliku z kwerendami lub na zrzucie istnieje zapis np.: ALTER TABLE adresy ADD COLUMN numerMieszkania INT AFTER numer; (dowolny typ całkowity, poprawnie również bez słowa COLUMN) oraz wynik działania udokumentowano zrzutem, na którym widoczne jest poprawnie wykonane zapytanie lub struktura tabeli z dodaną kolumną
ok. 2 min
Polecenie z arkusza
Zapytanie 4: Dodające kolumnę numerMieszkania typu całkowitego, do tabeli Adresy po kolumnie numer
ALTER TABLE adresy - zmiana struktury tabeli (w bazie ma nazwę małą literą, arkusz pisze „Adresy”),
ADD COLUMN numerMieszkania INT - nowa kolumna typu całkowitego; istniejące wiersze dostaną w niej NULL,
AFTER numer - miejsce kolumny: zaraz po numer, a nie na końcu tabeli.
Na zrzucie kw4.jpg widać komunikat albo strukturę tabeli: id, Osoby_id, ulica, numer, numerMieszkania, miasto.
Typowe błędy
Bez AFTER numer kolumna trafia na koniec tabeli, za miasto.
kwerendy.txtTekstzmienione: 3 linie
-- Zapytanie 1SELECT imie, nazwisko FROM osoby WHERE dataUr > '2000-12-31';-- Zapytanie 2SELECT DISTINCT miasto FROM adresy ORDER BY miasto;-- Zapytanie 3SELECT imie, nazwisko, telefony.numer FROM osoby JOIN telefony ON osoby.id = telefony.Osoby_id;-- Zapytanie 4ALTER TABLE adresy ADD COLUMN numerMieszkania INT AFTER numer;
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 8-30 · po tym etapie masz 20 z 43 kryteriów (pkt)
R.2.1 Plik obraz.png przeskalowano z zachowaniem proporcji do wysokości 200 px, jest on przezroczysty oraz widoczna jest na nim jedynie niebieska plakietka z pętelką
ok. 5 min
Polecenie z arkusza
Plik obraz.jpg wypakowany z archiwum należy skadrować, tak aby była widoczna tylko niebieska plakietka z pętelką (patrz obraz 2), ustawić tło przezroczyste oraz przeskalować z zachowaniem proporcji do wysokości 200 px. Obraz zapisać pod tą samą nazwą w formacie PNG
Trzy operacje w GIMP-ie: - kadr: narzędzie Kadrowanie wokół prawej plakietki. Uwaga na pętelki: do niebieskiej plakietki należy zielona nitka (zaczepiona w jej otworze), a niebieska nitka po lewej należy do zielonej plakietki - tak jest też na obrazie 2, - przezroczystość: Warstwa → Przezroczystość → Dodaj kanał alfa, potem Zaznaczanie rozmyte (różdżka) na białym tle i Usuń. Białe pole wewnątrz pętelki i otwór na nitkę są od tła oddzielone, więc zaznacza się je osobno (z klawiszem Shift). Białego procentu i koszyka nie wolno zaznaczyć - są częścią plakietki, - skala: Obraz → Skaluj obraz, łańcuch zamknięty, wysokość 200 px; szerokość wychodzi 92 px (kadr miał 286×620 px).
Zapis przez Plik → Wyeksportuj jakoobraz.png - JPEG nie ma przezroczystości. Podgląd: oryginał i gotowa plakietka na szachownicy, która pokazuje przezroczyste miejsca.
Typowe błędy
Zapis do JPEG - przezroczyste tło zamienia się na białe (albo czarne), a klucz wymaga przezroczystości.
Podgląd strony po tym kroku
Krok 9: Plik rejestracja.html w HTML5
ok. 2 min
Polecenie z arkusza
Składa się ze strony o nazwie rejestracja.html zapisanej w języku HTML5
Deklaracja <!DOCTYPE html> i szkielet z sekcjami head i body. Strona bez PHP - otwiera się ją prosto z dysku.
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.8 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css , formatowanie CSS pochodzi jedynie z tego arkusza Uwaga: kryterium to nie jest spełnione również, gdy zdający źle przypisał co najmniej jeden selektor do bloku (np. kropka zamiast #)
ok. 1 min
Polecenie z arkusza
Arkusz stylów w pliku o nazwie styl.css prawidłowo połączony z kodem strony
Nazwa pliku: styl.css. Całe formatowanie ma pochodzić z tego pliku.
Typowe błędy
Klucz odbiera R.3.8 także wtedy, gdy choć jeden selektor nie trafia w blok (np. kropka zamiast #).
R.2.4 Układ strony zdefiniowano dzieląc ją na bloki: boczny, baner, główny, blok paska postępu oraz stopkę. Zastosowano semantyczne znaczniki sekcji HTML5 zgodnie z ich znaczeniem, w tym do części nagłówkowej - header, stopki - footer, dopuszcza się zagnieżdżenie bloków div w znacznikach semantycznych
ok. 2 min
Polecenie z arkusza
Podział strony na blok boczny i obok niego bloki: baner, główny, blok paska postępu oraz na dole blok stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML 5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2
Blok boczny z promocjami to treść poboczna wobec formularza - znacznik <aside>. Baner to <header>, blok główny <main>, pasek postępu - <section> z identyfikatorem progress, stopka - <footer> (klucz R.2.4 wymaga wprost header i footer). Kolejność w kodzie odpowiada kolejności czytania: najpierw blok boczny, potem kolumna z banerem, formularzem i paskiem.
R.2.7 W bloku bocznym umieszczono tabelę zgodną z Obrazem 3 arkusza egzaminacyjnego, której pierwszy wiersz ma komórki nagłówkowe, zastosowano znaczniki <table>, <tr>, <th>, <td>
ok. 2 min
Polecenie z arkusza
Tabela, której pierwszy wiersz jest złożony z komórek nagłówkowych, wypełniona treściami widocznymi na obrazie 3
Pierwszy wiersz z komórkami nagłówkowymi <th> („co?”, „ile taniej?”), potem dwa wiersze z komórkami <td> - treść przepisana z obrazu 3.
R.2.8 W bloku głównym umieszczono trzy przyciski o treściach „Klient”, „Adres”, „Kontakt”
ok. 1 min
Polecenie z arkusza
Zawartość bloku głównego: Trzy przyciski o treściach: „Klient”, „Adres”, „Kontakt”, wciśnięcie dowolnego z nich wywołuje funkcję aktywującą kolejno blok pierwszy, drugi, trzeci
Trzy <button> jeden po drugim - wyglądają jak zakładki nad formularzem. Funkcję, którą wywołają, przycisk dostanie w części o JavaScripcie. Przyciski nie stoją w znaczniku <form>, więc nie wysyłają żadnego formularza i nie przeładowują strony.
Blok pierwszy z kontrolkami: Paragraf „Imię”, następnie pole edycyjne z podpowiedzią „Wpisz dane...”
Każda zakładka to <div> z klasą tab (wspólny wygląd) i identyfikatorem - client, address, contact - po którym skrypt pokaże albo ukryje blok. Podpis pola to akapit <p>, jak każe arkusz; podpowiedź - atrybut placeholder. Identyfikator pola (firstName) posłuży funkcji zatwierdzającej.
R.3.2 Pierwszy blok z kontrolkami ma dwa pola edycyjne oraz jedno typu date, dla pola do wpisywania imienia zdefiniowano placeholder "Wpisz dane..."
ok. 1 min
Polecenie z arkusza
Paragraf „Data urodzenia”, następnie pole edycyjne typu daty
Pole type="date" - przeglądarka pokazuje maskę dd.mm.rrrr i kalendarz (obraz 2). Wartość pola zawsze ma postać RRRR-MM-DD, niezależnie od tego, jak data wyświetla się na ekranie - widać to w konsoli na obrazie 6.
R.2.9 W bloku głównym znajdują się trzy bloki, w każdym z nich umieszczono przynajmniej jedno pole edycyjne oraz przynajmniej jeden podpis w paragrafie
ok. 1 min
Polecenie z arkusza
Blok trzeci z kontrolkami: Paragraf „Numer komórkowy”, następnie pole edycyjne typu numeru telefonu
Trzecia zakładka (id="contact"), pole type="tel" - telefon otwiera przy nim klawiaturę numeryczną. Każdy z trzech bloków ma już pole i podpis w akapicie (R.2.9).
R.3.4 Trzeci blok z kontrolkami ma jedno pole typu tel i jedno typu checkbox
ok. 1 min
Polecenie z arkusza
Pole wyboru podpisane „Akceptuję RODO”
Pole wyboru to type="checkbox", a podpis - <label> połączony z polem przez for/id (kliknięcie napisu też zaznacza pole). <br> przenosi pole do nowej linii, pod numer telefonu - jak na obrazie 5.
W sekcji progress druga, pusta sekcja z identyfikatorem bar - to ona będzie granatowym paskiem, którego szerokość zmienia skrypt. Zewnętrzna sekcja to szare tło całego paska.
R.2.5 W bloku bocznym zapisano nagłówek h2 "Sprawdź promocje" , w banerze zapisano nagłówek h1: "Zarejestruj się w sklepie" , w bloku stopki nagłówek h4: "Rejestrację do sklepu wykonał:" z numerem zdającego
ok. 1 min
Polecenie z arkusza
Zawartość stopki: nagłówek czwartego stopnia o treści: „Rejestrację do sklepu wykonał: ”, dalej wstawiony numer zdającego
Tym razem nie akapit, tylko <h4>. Na egzaminie po dwukropku wpisuje się swój numer zdającego (PESEL) - tutaj stoi imię i nazwisko autora rozwiązania. Z tym krokiem są wszystkie nagłówki z R.2.5.
R.4.8 Ustawiono dla bloku bocznego: box-shadow: 4px 4px 5px DimGray
ok. 2 min
Polecenie z arkusza
Dodatkowo dla bloku bocznego: szerokość 25%, wysokość 510 px, margines zewnętrzny górny i dolny 0, lewy i prawy 1%, cień bloku o przesunięciu 4 px w obu osiach, rozmyciu 5 px i kolorze DimGray
margin: 0 1% - góra i dół 0, lewa i prawa strona po 1%. box-shadow: 4px 4px 5px DimGray: przesunięcie w poziomie, przesunięcie w pionie, rozmycie i kolor - cień pada w prawo i w dół, jak na obrazie 2.
R.4.3 Ustawiono biały kolor czcionki dla bloków bocznego, banera i stopki oraz przycisków
R.4.6 Ustawiono wyrównanie tekstu do środka dla bloków bocznego, banera i stopki oraz rozmiar czcionki 130% dla przycisków
ok. 2 min
Polecenie z arkusza
Dla wszystkich przycisków: kolor tła SteelBlue, biały kolor czcionki, szerokość 20%, marginesy wewnętrzne 15 px, margines zewnętrzny górny 30 px, rozmiar czcionki 130%, bez obramowania
Selektor button łapie cztery przyciski: trzy zakładki i „Zatwierdź dane”. Szerokość 20% liczy się od szerokości rodzica - zakładek od bloku głównego, a przycisku zatwierdzającego od jego zakładki, dlatego jest węższy (obraz 5). Ta reguła zamyka biel czcionki (R.4.3) oraz wyśrodkowanie z rozmiarem 130% (R.4.6).
Krok 39: Bloki z kontrolkami: wygląd i widoczny tylko pierwszy
Kryteria:
R.5.5 W stanie początkowym jest pokazany pierwszy blok z imieniem i nazwiskiem, a pozostałe są utworzone i ukryte (w skrypcie lub CSS)
ok. 2 min
Polecenie z arkusza
Dla trzech bloków z kontrolkami: kolor tła LightBlue, margines zewnętrzny prawy 80 px, marginesy wewnętrzne 10 px. W stanie początkowym jest widoczny tylko pierwszy blok z kontrolkami
Klasa .tab - wspólne cechy trzech bloków. Drugi i trzeci blok ukrywa display: none: blok znika i nie zajmuje miejsca, więc każda zakładka pojawi się w tym samym miejscu pod przyciskami (obrazy 4 i 5). Bloki są w kodzie strony, tylko niewidoczne - skrypt będzie je pokazywał.
R.4.2 Ustawiono kolor tła Linen dla body, SteelBlue dla bloków bocznego, banera i stopki oraz przycisków, LightGrey dla bloku paska postępu oraz LightBlue dla bloków z kontrolkami
R.4.7 Ustawiono marginesy wewnętrzne (padding) 15px dla przycisków, 10px dla bloków z kontrolkami oraz marginesy zewnętrzne (margin) dla bloku bocznego: jedynie lewy i prawy 1%, górny 30px dla przycisków, prawy 80px dla bloków z kontrolkami i dolny 10px dla paska postępu
R.5.2 W stanie początkowym pasek postępu ma szerokość 4% (w skrypcie lub CSS)
R.4.4 Ustawiono wysokość bloku bocznego 510px, banera 80px, głównego 400px oraz 30px dla paska postępu
ok. 1 min
Polecenie z arkusza
Dla pustego bloku w bloku paska postępu: kolor tła Navy, szerokość 4%, wysokość 30 px
Granatowy pasek o szerokości 4% szarego tła - to stan początkowy, od którego skrypt zacznie liczyć (R.5.2). Wysokość 30 px nadaje wysokość całemu paskowi, bo zewnętrzna sekcja nie ma własnej. Komplet wysokości z R.4.4: 510, 80, 400 i 30 px.
R.4.5 Ustawiono szerokość bloku bocznego 25%, banera, głównego oraz paska postępu 73% (width lub grid-template-columns lub flex) oraz 20% dla przycisków i 100% dla tabeli
R.4.9 Ustawiono obramowanie tabeli linią kropkowaną o szerokości 1 px i kolorze Navy oraz brak obramowania dla przycisków
ok. 1 min
Polecenie z arkusza
Dla tabeli: szerokość 100%, obramowanie linią kropkowaną o szerokości 1 px i kolorze Navy
Linia kropkowana to dotted (kreskowana byłaby dashed). Ta reguła zamyka szerokości (R.4.5) i obramowania: kropkowana tabela i przyciski bez ramki (R.4.9).
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z obrazem 2 w arkuszu egzaminacyjnym, w bloku głównym może być widoczny jeden blok z kontrolkami, wszystkie trzy lub żaden (prawidłowo zastosowano właściwości CSS decydujące o układzie strony, np. float i clear albo display flex albo grid)
ok. 2 min
Polecenie z arkusza
Podział strony na blok boczny i obok niego bloki: baner, główny, blok paska postępu oraz na dole blok stopki. Podział zrealizowany wyłącznie za pomocą semantycznych znaczników sekcji języka HTML 5 tak, aby po uruchomieniu w przeglądarce wygląd układu bloków był zgodny z obrazem 2
float: left dla czterech bloków. Blok boczny staje przy lewej krawędzi, baner (73%) mieści się obok niego. Blok główny nie zmieści się już w tym wierszu obok banera, więc przechodzi niżej - ale wysoki blok boczny wciąż tam stoi, dlatego blok główny ustawia się przy jego prawej krawędzi, pod banerem. Tak samo pasek postępu. clear: both stawia stopkę pod wszystkimi blokami pływającymi.
Typowe błędy
Bez float dla banera, bloku głównego i paska ich tło wchodzi pod blok boczny (pływający element przykrywa zwykłe bloki), choć tekst omija go z boku.
Kroki 44-51 · po tym etapie masz 43 z 43 kryteriów (pkt)
Krok 44: Funkcja aktywująca: ukrycie wszystkich zakładek
Kryteria:
R.5.1 Skrypt zapisano w języku JavaScript i zawiera on przynajmniej jedną instrukcję
ok. 2 min
Polecenie z arkusza
Funkcja aktywująca: ukrywa wszystkie zakładki
Skrypt na końcu <body>, w znaczniku <script>. Funkcja showTab dostanie w parametrze tabId identyfikator zakładki, którą ma pokazać. Najpierw ukrywa wszystkie trzy: style.display = "none" - ta sama wartość, której używa arkusz stylów. Nikt jej jeszcze nie wywołuje, więc na stronie nic się nie zmienia.
Pokazuje jedynie tę zakładkę (blok), której przycisk wybrano
Po ukryciu wszystkich jedna linia pokazuje wybraną: display = "block" przywraca zwykły blok. Kolejność „najpierw ukryj wszystkie, potem pokaż jedną” sprawia, że nie trzeba pamiętać, która zakładka była otwarta.
R.3.6 Przynajmniej jeden przycisk zakładek ma zdefiniowane zdarzenie onClick z przypisaną funkcją
R.5.6 Po kliknięciu w dowolny przycisk (nazwę bloku) jest pokazywany odpowiadający mu blok, a pozostałe są ukrywane
ok. 2 min
Polecenie z arkusza
Funkcja aktywująca jest wywoływana przez wciśnięcie dowolnego przycisku zakładki w bloku głównym
Atrybut onclick z wywołaniem funkcji i identyfikatorem zakładki w apostrofach - atrybut stoi w cudzysłowach, więc tekst w środku musi mieć apostrofy. W podglądzie można już klikać zakładki: „Adres” pokazuje blok z ulicą (obraz 4), „Kontakt” - blok z telefonem (obraz 5).
R.5.3 Po opuszczeniu przynajmniej jednego pola edycyjnego pasek postępu zwiększa swoją szerokość o 12%
ok. 2 min
Polecenie z arkusza
Funkcja modyfikuje właściwość stylu dla pustego bloku wewnątrz bloku paska postępu, w ten sposób, że jego szerokość jest zwiększana o 12%, np. po utracie focusa za pierwszym razem wartość wynosi 16%; za drugim razem jest to 28%, trzecim 40% i tak dalej
Zmienna progress stoi poza funkcją, więc pamięta wartość między wywołaniami - zmienna zadeklarowana w środku funkcji przy każdym wywołaniu startowałaby od nowa. Startuje od 4 (szerokość z CSS), każde wywołanie dodaje 12, a nowa szerokość trafia do style.width jako tekst z jednostką: progress + "%" daje np. „16%”.
Krok 48: Każde pole edycyjne wywołuje funkcję po utracie focusa
Kryteria:
R.3.5 Przynajmniej jedno pole edycyjne ma zdefiniowane zdarzenie onBlur lub onFocusOut z przypisaną funkcją
ok. 2 min
Polecenie z arkusza
Dla wszystkich pól edycyjnych – utrata focusa powoduje wywołanie funkcji zmieniającej wartość paska postępu
Utrata focusa to zdarzenie blur - kursor opuszcza pole (kliknięcie gdzie indziej albo klawisz Tab). Atrybut onblur dostaje wszystkie siedem pól edycyjnych: imię, nazwisko, data, ulica, numer, miasto i telefon; pole wyboru RODO nie jest polem edycyjnym. W podglądzie: kliknięcie w pole imienia i potem obok wydłuża pasek do 16%.
R.5.4 Szerokość paska postępu nie może być większa niż 100%, zastosowano warunek
ok. 2 min
Polecenie z arkusza
Należy zabezpieczyć funkcję, aby wartość szerokości nigdy nie była wyższa niż 100%
Rachunek: 4 + 8 · 12 = 100, więc po ósmej utracie focusa pasek jest pełny, a po dziewiątej miałby 112% i wyszedłby poza szare tło. Warunek if przycina wartość do 100. Stoi przed ustawieniem szerokości - do stylu trafia już poprawiona liczba.
Krok 50: Funkcja zatwierdzająca: wartości w konsoli
Kryteria: ,
R.5.7 Po kliknięciu w przycisk zatwierdzający wyświetlone są w konsoli przeglądarki wartości wpisane w pola edycyjne
R.5.8 W funkcji zatwierdzającej zastosowano funkcję lub zestaw funkcji odwołujących się do wszystkich pól edycyjnych i pola wyboru na stronie
ok. 3 min
Polecenie z arkusza
Funkcja zatwierdzająca pobiera wartość z każdego pola edycyjnego i pola wyboru. Wartości wyświetlane są w konsoli przeglądarki (obraz 6). Dla uproszczenia wszelką walidację należy pominąć
Każde pole edycyjne odczytuje właściwość value elementu znalezionego przez getElementById, a pole wyboru - .checked (true albo false). Obraz 6 pokazuje przy zgodzie słowo „on”: to .value pola wyboru, które zawsze wynosi „on”, także gdy pole nie jest zaznaczone (sprawdzone w przeglądarce), więc nic nie mówi o zgodzie. console.log wypisuje jeden napis z wartościami po przecinku, jak na obrazie 6. Walidacji nie ma - tak każe arkusz.
Krok 51: Przycisk „Zatwierdź dane” wywołuje funkcję
Kryteria: ,
R.3.7 Przycisk do zatwierdzenia danych ma zdefiniowane zdarzenie onClick z przypisaną funkcją
R.5.9 Zastosowano znaczące nazewnictwo dla wszystkich zmiennych i funkcji w języku polskim lub angielskim. Nazwy odzwierciedlają cel zastosowania
ok. 1 min
Polecenie z arkusza
Funkcja zatwierdzająca jest wywoływana po wybraniu przycisku „Zatwierdź dane”
Atrybut onclick z wywołaniem confirmData(). Wynik widać w konsoli (F12, zakładka Console). Nazwy funkcji i zmiennych mówią, co robią i co przechowują (showTab, increaseProgress, confirmData, progress, houseNumber) - kryterium R.5.9.
Kroki 52-53 · po tym etapie masz 43 z 43 kryteriów (pkt)
Krok 52: Pasek postępu liczony z wypełnionych pól
ok. 4 min
Polecenie z arkusza
Funkcja jest uproszczona, zakładamy że każda utrata focusa kontrolki jest równa wpisaniu do niej danych i powoduje zwiększenie szerokości paska
Arkusz świadomie upraszcza pasek, a skutek widać w przeglądarce: dziewięć razy kliknięte i opuszczone puste pole imienia daje w wersji egzaminacyjnej pasek 100% - formularz „wypełniony”, choć nic w nim nie ma. Poprawka: funkcja przy każdym wywołaniu liczy od nowa, ile pól edycyjnych ma niepustą wartość (trim pomija same spacje), i z tego wylicza szerokość: 4% + 12% za pole, najwyżej 100% (Math.min). Sprawdzone: puste pole opuszczone 9 razy - 4%, wpisane „Anna” - 16%, ponowne opuszczenie - nadal 16%, wyczyszczenie pola - z powrotem 4%. Zmienna globalna progress przestaje być potrzebna. Stara wersja zostaje w komentarzu. Na egzaminie wystarczy wersja wcześniejsza - arkusz każe pominąć sprawdzanie, czy dane wpisano.
Krok 53: Nasłuchiwacze zdarzeń i zgoda RODO przed zatwierdzeniem
ok. 4 min
Polecenie z arkusza
Funkcja aktywująca jest wywoływana przez wciśnięcie dowolnego przycisku zakładki w bloku głównym
Atrybuty onclick i siedem kopii onblur znikają z HTML-u. Przyciski zakładek niosą nazwę swojej zakładki w atrybucie data-tab, a pętla w skrypcie podpina im jeden nasłuchiwacz addEventListener("click", ...), który czyta ją przez dataset.tab. Druga pętla podpina zdarzenie blur wszystkim polom edycyjnym naraz - nowe pole w formularzu nie wymaga pamiętania o atrybucie. Funkcja zatwierdzająca dostaje jedno sprawdzenie, bez którego rejestracja w prawdziwym sklepie nie przejdzie: bez zaznaczonej zgody RODO pokazuje komunikat i nie wypisuje danych (sprawdzone w przeglądarce). Na egzaminie wystarczy wersja wcześniejsza - klucz w R.3.5 - R.3.7 mówi wprost o zdarzeniach onBlur i onClick, więc atrybuty są najpewniejszą formą, a walidację arkusz każe pominąć.
rejestracja.htmlHTMLzmienione: 24 linie
<!DOCTYPE html><htmllang="pl"><head> <metacharset="UTF-8"> <title>Sklep - rejestracja</title> <linkrel="stylesheet"href="styl.css"></head><body> <aside> <imgsrc="obraz.png"alt="promocje"> <h2>Sprawdź promocje</h2> <table> <tr> <th>co?</th> <th>ile taniej?</th> </tr> <tr> <td>ubrania</td> <td>15%</td> </tr> <tr> <td>buty</td> <td>25%</td> </tr> </table> </aside> <header> <h1>Zarejestruj się w sklepie</h1> </header> <main> <buttondata-tab="client">Klient</button> <buttondata-tab="address">Adres</button> <buttondata-tab="contact">Kontakt</button> <divclass="tab"id="client"> <p>Imię</p> <inputtype="text"id="firstName"placeholder="Wpisz dane..."> <p>Nazwisko</p> <inputtype="text"id="lastName"> <p>Data urodzenia</p> <inputtype="date"id="birthDate"> </div> <divclass="tab"id="address"> <p>Ulica</p> <inputtype="text"id="street"> <p>Numer</p> <inputtype="number"id="houseNumber"> <p>Miasto</p> <inputtype="text"id="city"> </div> <divclass="tab"id="contact"> <p>Numer komórkowy</p> <inputtype="tel"id="phone"> <br> <inputtype="checkbox"id="rodo"> <labelfor="rodo">Akceptuję RODO</label> <br> <buttonid="confirm">Zatwierdź dane</button> </div> </main> <sectionid="progress"> <sectionid="bar"></section> </section> <footer> <h4>Rejestrację do sklepu wykonał: Bartosz Bryniarski</h4> </footer> <script>function showTab(tabId) {document.getElementById("client").style.display = "none";document.getElementById("address").style.display = "none";document.getElementById("contact").style.display = "none";document.getElementById(tabId).style.display = "block"; }const editFields = document.querySelectorAll("main input:not([type=checkbox])");// pasek liczy WYPEŁNIONE pola, a nie liczbę opuszczeń polafunction increaseProgress() {let filled = 0;for (let field of editFields) {if (field.value.trim() != "") { filled = filled + 1; } }let progress = Math.min(4 + filled * 12, 100);document.getElementById("bar").style.width = progress + "%"; }/* Wersja z egzaminu - każda utrata focusa to +12%: let progress = 4; function increaseProgress() { progress = progress + 12; if (progress > 100) { progress = 100; } document.getElementById("bar").style.width = progress + "%"; } */function confirmData() {let firstName = document.getElementById("firstName").value;let lastName = document.getElementById("lastName").value;let birthDate = document.getElementById("birthDate").value;let street = document.getElementById("street").value;let houseNumber = document.getElementById("houseNumber").value;let city = document.getElementById("city").value;let phone = document.getElementById("phone").value;let rodo = document.getElementById("rodo").checked;if (!rodo) { alert("Zaznacz zgodę RODO, aby zatwierdzić dane");return; } console.log(firstName + ", " + lastName + ", " + birthDate + ", " + street + ", " + houseNumber + ", " + city + ", " + phone + ", " + rodo); }// nasłuchiwacze zamiast atrybutów onclick i onblur w HTML-ufor (let tabButton ofdocument.querySelectorAll("button[data-tab]")) { tabButton.addEventListener("click", function () { showTab(tabButton.dataset.tab); }); }for (let field of editFields) { field.addEventListener("blur", increaseProgress); }document.getElementById("confirm").addEventListener("click", confirmData); </script></body></html>
Podgląd strony po tym kroku (rejestracja.html)
Etap 6: Oddanie pracy
Krok 54 · po tym etapie masz 43 z 43 kryteriów (pkt)
Krok 54: Plik przeglądarka.txt i nagranie płyty
ok. 5 min
Polecenie z arkusza
Po zakończeniu pracy utwórz plik tekstowy o nazwie przeglądarka.txt. Zapisz w nim nazwę przeglądarki internetowej, w której weryfikowana była poprawność działania witryny. Umieść go w folderze z numerem zdającego. Nagraj płytę z rezultatami pracy.
W przeglądarka.txt wpisuje się nazwę przeglądarki, w której sprawdzana była strona.
W folderze z numerem zdającego: import.png, kw1.jpg - kw4.jpg, kwerendy.txt, obraz.png (plakietka), przeglądarka.txt, rejestracja.html, styl.css. Płytę trzeba nagrać, sprawdzić jej odczyt i opisać numerem zdającego.
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.