INF.03-02-25.06-SGCzerwiec 2025 · 34 kroki · ok. 81 min · 37 kryteriów z klucza
Rozwiązanie krok po kroku: Planer zadań z notatkami (Nowoczesny kod (grid))
To drugi sposób rozwiązania tego samego arkusza: planer zadań z bazą notatki, stroną notatki.html i skryptem, który przekreśla wykonane zadania i dodaje nowe. Obie wersje spełniają wszystkie 37 kryteriów klucza - różni je sposób pisania kodu.
Czym ta wersja różni się od podstawowej:
siatka CSS z nazwanymi obszarami (grid-template-areas) zamiast pięciu bloków z float: left - układ z ilustracji 3 jest narysowany wprost w kodzie, a szerokości 20% / 80% stoją w grid-template-columns, co klucz dopuszcza wprost,
kolory z arkusza w zmiennych CSS w :root,
przekreślenie przez klasę CSS (.done) zamiast stylu wpisywanego z JavaScriptu - cały wygląd zostaje w styl.css,
jeden nasłuchiwacz na całej liście (delegacja zdarzeń) zamiast onclick przy każdym przycisku - działa też dla zadań dodanych później,
pole i przycisk „Dodaj” w formularzu - zadanie dodaje się także klawiszem Enter,
skrypt podpięty w <head> z atrybutem defer, textContent zamiast innerText, zapytania SQL z aliasami i JOIN ... ON.
Kroki nadal idą zdanie po zdaniu za treścią arkusza, a podgląd rośnie z każdym krokiem. Obraz, baza i zadania.txt pochodzą z prawdziwego archiwum pliki2; zrzuty to wyniki zapytań wykonanych na tej bazie w MariaDB.
Jak liczą się punkty. Klucz ma 37 kryteriów (R.1.1 - R.5.7), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 28 punktów. 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-6 · po tym etapie masz 6 z 37 kryteriów (pkt)
Krok 1: Baza danych notatki
Kryteria:
R.1.1 Wykonany import tabel do bazy danych notatki czynność udokumentowana w pliku import.png
ok. 2 min
Polecenie z arkusza
Utwórz bazę danych o nazwie notatki, z zestawem polskich znaków (np. utf8_unicode_ci).
W phpMyAdmin Nowa, nazwa notatki, porównywanie utf8_unicode_ci - albo jedno zapytanie w zakładce SQL:
CREATE DATABASE notatki CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Typowe błędy
Baza i jedna z tabel nazywają się tak samo (notatki) - baza to pojemnik, tabela leży w środku. Zapytania wykonuj przy zaznaczonej bazie.
Krok 2: Import tabel i zrzut import.png
Kryteria:
R.1.1 Wykonany import tabel do bazy danych notatki czynność udokumentowana w pliku import.png
ok. 3 min
Polecenie z arkusza
Do bazy zaimportuj tabele z pliku baza.sql z rozpakowanego archiwum. Wykonaj zrzut ekranu po imporcie. Zrzut zapisz w formacie PNG pod nazwą import. Nie kadruj zrzutu.
Zaznacz bazę notatki, Import → baza.sql → Wykonaj. Powstają dwie tabele z ilustracji 1: osoby (4 wiersze) i notatki (13 wierszy) z kluczem obcym Osoby_id - jedna osoba ma wiele notatek. Nazwa Osoby_id ma wielką literę; w zapytaniach pisz ją tak samo, bo na serwerach linuksowych wielkość liter w nazwach bywa istotna.
Potem Print Screen całego ekranu z paskiem zadań i zapis jako import.png (zrzuty kwerend będą w JPEG).
Typowe błędy
Wykadrowany zrzut (samo okno przeglądarki, bez paska zadań) nie jest oceniany.
Krok 3: Zapytanie 1: najmniejszy priorytet osoby o id 3
Kryteria: ,
R.1.2 Zapisany plik kwerendy.txt zawierający co najmniej jedno zapytanie SQL, wynikające z treści zadania
R.1.3 Wykonane zapytanie 1 wybierające jedynie najmniejszą wartość priorytetu notatki dla osoby o id równym 3. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT MIN(priorytet) FROM notatki WHERE Osoby_id = 3; rozwiązanie alternatywne z LIMIT 1 i ORDER BY oraz wynik działania udokumentowany zrzutem, na którym jest widoczna jedynie wartość 2
ok. 3 min
Polecenie z arkusza
Zapytanie 1: wybierające jedynie najmniejszą wartość priorytetu notatki dla osoby o id równym 3.
SELECT MIN(priorytet) AS najnizszy_priorytet - funkcja grupująca zwraca jedną liczbę, a alias nadaje kolumnie wyniku nazwę, którą da się przeczytać (bez niego kolumna nazywa się MIN(priorytet)),
WHERE Osoby_id = 3 - arkusz podaje id, więc złączenie z tabelą osoby nie jest potrzebne.
Wynik: 2. Zapytania zapisuj w kwerendy.txt z komentarzem -- nad każdym. Zrzut: kw1.jpg.
kwerendy.txtTekstnowy plik
-- Zapytanie 1SELECT MIN(priorytet) AS najnizszy_priorytetFROM notatkiWHERE Osoby_id = 3;
Podgląd strony po tym kroku
Krok 4: Zapytanie 2: notatki z cząstką „na” w nazwie
Kryteria:
R.1.4 Wykonane zapytanie 2 wybierające jedynie nazwę notatki i jej priorytet dla notatek, których nazwa zawiera cząstkę „na”. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT nazwa, priorytet FROM notatki WHERE nazwa LIKE "%na%"; oraz wynik działania udokumentowany zrzutem, na którym są widoczne dokładnie 4 rekordy z danymi: Gimnastyka 1; Projekt na geografię 2; Wyjazd na wakacje 5; Weterynarz Brutus 5
ok. 3 min
Polecenie z arkusza
Zapytanie 2: wybierające jedynie nazwę notatki i jej priorytet dla notatek, których nazwa zawiera cząstkę „na”.
LIKE '%na%' - % to dowolny ciąg znaków, więc „na” może stać gdziekolwiek: Gimnastyka, Projekt na geografię, Wyjazd na wakacje, Weterynarz Brutus (4 wiersze). Napis we wzorcu w apostrofach - to zapis ze standardu SQL; cudzysłów działa w MariaDB, ale w innych bazach oznacza nazwę kolumny. Zrzut: kw2.jpg.
Typowe błędy
LIKE 'na%' znajdzie tylko nazwy zaczynające się od „na” - zero wierszy.
kwerendy.txtTekstzmienione: 5 linii
-- Zapytanie 1SELECT MIN(priorytet) AS najnizszy_priorytetFROM notatkiWHERE Osoby_id = 3;-- Zapytanie 2SELECT nazwa, priorytetFROM notatkiWHERE nazwa LIKE '%na%';
Podgląd strony po tym kroku
Krok 5: Zapytanie 3: imię i notatka dla priorytetu 5
Kryteria:
R.1.5 Wykonano zapytanie 3 wybierające jedynie imię osoby i odpowiadającą mu nazwę notatki dla notatek, których priorytet jest równy 5. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, nazwa FROM notatki JOIN osoby ON osoby.id = Osoby_id WHERE priorytet=5; (możliwe również INNER JOIN lub porównanie kluczy po WHERE) oraz wynik działania udokumentowany zrzutem, na którym widoczne jest dokładnie 5 rekordów: dla Krzyśka wyświetlono Wyprowadzić psa, Spacer z kumplem; dla Eweliny wyświetlono Wyjazd na wakacje, Weterynarz Brutus, Lekarz
ok. 4 min
Polecenie z arkusza
Zapytanie 3: wybierające jedynie imię osoby i odpowiadającą mu nazwę notatki dla notatek, których priorytet jest równy 5. Należy posłużyć się relacją.
„Posłużyć się relacją” to złączenie tabel:
FROM notatki AS n JOIN osoby AS o - krótkie aliasy tabeln i o,
ON o.id = n.Osoby_id - warunek złączenia: id osoby równa się kluczowi obcemu notatki,
SELECT o.imie, n.nazwa i WHERE n.priorytet = 5 - każda kolumna z prefiksem aliasu, więc od razu widać, z której tabeli pochodzi (i nie ma kłopotu z id, które jest w obu).
Zapis JOIN ... ON oddziela warunek łączenia tabel od warunku filtrowania (WHERE) - w starszym zapisie FROM notatki, osoby WHERE ... oba lądują w jednym miejscu i łatwo zgubić złączenie. Wynik: 5 wierszy (Krzysiek ×2, Ewelina ×3). Zrzut: kw3.jpg.
kwerendy.txtTekstzmienione: 6 linii
-- Zapytanie 1SELECT MIN(priorytet) AS najnizszy_priorytetFROM notatkiWHERE Osoby_id = 3;-- Zapytanie 2SELECT nazwa, priorytetFROM notatkiWHERE nazwa LIKE '%na%';-- Zapytanie 3SELECT o.imie, n.nazwaFROM notatki AS nJOIN osoby AS o ON o.id = n.Osoby_idWHERE n.priorytet = 5;
Podgląd strony po tym kroku
Krok 6: Zapytanie 4: liczba notatek każdej osoby
Kryteria:
R.1.6 Wykonane zapytanie 4 liczące dla każdego imienia osoby liczbę jego notatek. Kwerenda wybiera jedynie imię i odpowiadającą mu liczbę notatek. W pliku z kwerendami lub na zrzucie istnieje zapis np.: SELECT imie, COUNT(Osoby_id) FROM notatki JOIN osoby ON Osoby_id = osoby.id GROUP BY imie; (możliwe również INNER JOIN lub porównanie kluczy po WHERE, w COUNT * lub dowolne inne pole) oraz wynik działania udokumentowano zrzutem, na którym są widoczne dokładnie 4 rekordy z danymi: Ewelina 5; Grześ 1; Krzysiek 4; Paula 3
ok. 4 min
Polecenie z arkusza
Zapytanie 4: liczące dla każdego imienia osoby liczbę jego notatek. Kwerenda wybiera jedynie imię i odpowiadającą mu liczbę notatek. Należy posłużyć się relacją.
To samo złączenie, a do tego GROUP BY o.imie i COUNT(n.id) AS liczba_notatek: wiersze o tym samym imieniu tworzą grupę, a COUNT liczy notatki w każdej. Grupowanie po imieniu, bo arkusz mówi „dla każdego imienia” - przy dwóch osobach o tym samym imieniu wynik by je połączył (w tej bazie imiona się nie powtarzają). Wynik: Ewelina 5, Grześ 1, Krzysiek 4, Paula 3. Zrzut: kw4.jpg.
Typowe błędy
Kolumna spoza GROUP BY w SELECT (np. n.nazwa) to w MySQL 8 błąd, a w MariaDB przypadkowa wartość z grupy.
kwerendy.txtTekstzmienione: 6 linii
-- Zapytanie 1SELECT MIN(priorytet) AS najnizszy_priorytetFROM notatkiWHERE Osoby_id = 3;-- Zapytanie 2SELECT nazwa, priorytetFROM notatkiWHERE nazwa LIKE '%na%';-- Zapytanie 3SELECT o.imie, n.nazwaFROM notatki AS nJOIN osoby AS o ON o.id = n.Osoby_idWHERE n.priorytet = 5;-- Zapytanie 4SELECT o.imie, COUNT(n.id) AS liczba_notatekFROM notatki AS nJOIN osoby AS o ON o.id = n.Osoby_idGROUP BY o.imie;
Podgląd strony po tym kroku
Etap 2: Grafika i strona HTML
Kroki 7-15 · po tym etapie masz 17 z 37 kryteriów (pkt)
Krok 7: Przeskalowanie grafiki obraz.jpg
Kryteria:
R.2.1 Plik obraz.jpg przeskalowany z zachowaniem proporcji do wysokości 610 px, odpowiadająca temu szerokość wynosi 458 px (± 5 px)
ok. 3 min
Polecenie z arkusza
Plik obraz.jpg, wypakowany z archiwum, należy przeskalować z zachowaniem proporcji do wysokości 610 px.
Oryginał 480 × 640 px. W GIMP-ie Obraz → Skaluj obraz: wysokość 610 px przy zamkniętym łańcuchu - szerokość wyjdzie 458 px (480 · 610 / 640), a klucz sprawdza 458 ±5 px.
Podgląd strony po tym kroku
Krok 8: Plik notatki.html: HTML5, język i kodowanie
Kryteria:
R.2.2 W pliku notatki.html zapisana deklaracja HTML5 <!DOCTYPE HTML>, deklaracja języka zawartości: polski np. <html lang="pl">, w sekcji head znajduje się jawnie podany standard kodowania polskich znaków
ok. 2 min
Polecenie z arkusza
Składa się ze strony o nazwie notatki.html. Zapisana w języku HTML5. Zadeklarowany polski język zawartości witryny. Jawnie zastosowany właściwy standard kodowania polskich znaków.
<!DOCTYPE html>, <html lang="pl"> i <meta charset="UTF-8"> jako pierwszy element <head>. Strona to czysty HTML z JavaScriptem - otwiera się nawet prosto z dysku, bez XAMPP-a.
R.3.2 Strona zawiera działające połączenie z zewnętrznym arkuszem stylów o nazwie styl.css, formatowanie CSS pochodzi jedynie z tego arkusza
ok. 1 min
Polecenie z arkusza
Tytuł strony widoczny na karcie przeglądarki: „Planer zadań”. Arkusz stylów w pliku o nazwie styl.css prawidłowo połączony z kodem strony.
<title> - tekst karty (R.2.3), <link rel="stylesheet" href="styl.css"> - połączenie z arkuszem stylów (R.3.2), bez ukośnika />. Meta viewport każe telefonom pokazywać stronę w prawdziwej szerokości ekranu.
R.2.4 W sekcji body zdefiniowany jest podział na bloki za pomocą semantycznych znaczników HTML 5: aside, header, nav (lub inny) , main, footer
ok. 2 min
Polecenie z arkusza
Podział strony na blok boczny i obok niego bloki: blok nagłówkowy, blok dodający zadanie, blok główny, blok stopki. Podział strony na bloki zrealizowany za pomocą semantycznych znaczników bloków języka HTML5 tak, aby po uruchomieniu w przeglądarce układ bloków na stronie był zgodny z ilustracją 3.
Znaczniki z tabeli 4 arkusza i klucza R.2.4: <aside>, <header>, <nav> (blok dodający zadanie), <main>, <footer>. Wszystkie są dziećmi <body>, a o tym, gdzie który stanie, zdecyduje siatka CSS - nie kolejność w kodzie. <aside> stoi pierwszy, bo tak czyta stronę czytnik ekranu, ale przy siatce z obszarami mógłby stać na końcu.
Krok 13: Blok nawigacyjny: formularz z polem i przyciskiem
Kryteria: ,
R.2.7 W bloku nawigacyjnym umieszczone pole edycyjne i przycisk "Dodaj"
R.3.3 W polu edycyjnym wyświetla się podpowiedź "Dodaj zadanie…", zastosowany do pola atrybut placeholder
ok. 3 min
Polecenie z arkusza
Zawartość bloku nawigacyjnego: pole edycyjne z podpowiedzią o treści „Dodaj zadanie...”. Przycisk „Dodaj”, którego wciśnięcie powoduje wywołanie funkcji w skrypcie.
Pole i przycisk są w <form> - dzięki temu zadanie doda się zarówno kliknięciem „Dodaj”, jak i klawiszem Enter w polu (przeglądarka wysyła formularz w obu przypadkach). Formularz nie ma action, bo nic nie trafia na serwer: wysłanie przechwyci skrypt.
placeholder - podpowiedź w pustym polu (R.3.3),
aria-label - nazwa pola dla czytnika ekranu; podpowiedź znika przy pisaniu, więc nie zastępuje etykiety,
required - przeglądarka nie wyśle pustego pola i sama pokaże komunikat,
type="submit" przy przycisku - to on wysyła formularz.
Typowe błędy
value="Dodaj zadanie..." zamiast placeholder wpisuje tekst na stałe - R.3.3 przepada.
Krok 14: Blok główny: lista sześciu zadań z przyciskami
Kryteria: ,
R.2.8 W bloku głównym umieszczona jedna lista punktowana z sześcioma elementami, zastosowane znaczniki <ul> i <li>
R.2.9 Wewnątrz każdego elementu <li> znajduje się przycisk o treści "Wykonane"
ok. 3 min
Polecenie z arkusza
Zawartość bloku głównego: lista punktowana (nieuporządkowana) zawierająca w stanie początkowym 6 elementów. Każdy element listy zawiera: wpis (kolejne wpisy można skopiować do kodu HTML z pliku zadania.txt), przycisk o treści „Wykonane”, którego wciśnięcie powoduje wywołanie skryptu dla danego elementu listy.
<ul id="task-list"> z sześcioma <li> - teksty skopiowane z zadania.txt, a w każdym elemencie przycisk „Wykonane” (R.2.9). Przyciski nie mają onclick ani identyfikatorów: jeden nasłuchiwacz na liście obsłuży wszystkie, także te dodane później. type="button" mówi wprost, że przycisk niczego nie wysyła - gdyby lista kiedyś trafiła do formularza, nie zacząłby go wysyłać.
Typowe błędy
Przycisk poza <li> nie spełnia R.2.9, a skrypt nie wiedziałby, które zadanie przekreślić.
Domyślne formatowanie wszystkich selektorów: krój czcionki Verdana.
Na początku styl.css zmienne CSS w :root - pięć kolorów z arkusza, nazwanych według roli (akcent, blok główny, parzyste, kursor, cień). MediumPurple występuje w trzech miejscach (bloki, przyciski, ramka listy), więc ustawiony raz w --color-accent zmienia się jedną linią.
Potem selektor uniwersalny * z font-family: Verdana, sans-serif (R.4.1) - rodzina zastępcza sans-serif na wypadek braku Verdany.
Dla bloku bocznego: szerokość 20%, wysokość 610 px.
Szerokość bloku bocznego wynika z siatki, więc ten krok od razu ją zakłada:
display: grid na <body> - bloki stają się elementami siatki,
grid-template-columns: 20% 80% - dwie kolumny: 20% na blok boczny, 80% na resztę. Klucz R.4.5 dopuszcza szerokości zapisane właśnie tak („width lub grid-template-columns lub flex”),
grid-template-areas - mapa strony narysowana napisami: każdy wiersz w cudzysłowie to wiersz siatki, każde słowo - komórka. Nazwa aside powtórzona w czterech wierszach znaczy, że blok boczny zajmuje całą lewą kolumnę, jak na ilustracji 3.
aside dostaje grid-area: aside (wejdź do obszaru o tej nazwie) i wysokość 610 px. Pozostałe bloki trafią do swoich obszarów w następnych krokach - do tego czasu przeglądarka układa je w kolejnych wolnych komórkach.
width: 100% - cała szerokość komórki bloku bocznego, wysokość 610 px jak blok. Obraz może się lekko zniekształcić przy innej proporcji okna; arkusz tego wymaga. W prawdziwym projekcie dodałoby się object-fit: cover (przycięcie zamiast ściśnięcia), ale klucz sprawdza wymiary, więc tu go nie ma.
Krok 19: Nagłówek, nawigacja i stopka: wspólne style
Kryteria:
R.4.6 Ustawione wyrównanie tekstu do środka dla bloku nagłówkowego, stopki i bloku nawigacyjnego
ok. 3 min
Polecenie z arkusza
Dla bloku nagłówkowego, stopki i nawigacyjnego: kolor tła MediumPurple, biały kolor czcionki, szerokość 80%, wysokość 50 px, wyrównanie tekstu do środka, cień tekstu o przesunięciu 4 px w obu osiach i kolorze DimGray.
Jedna reguła dla trzech bloków: tło ze zmiennej, biały tekst, 50 px wysokości, wyśrodkowanie i text-shadow: 4px 4px z kolorem cienia (tabela 2 arkusza; rozmycie pominięte, bo arkusz go nie podaje).
Szerokości 80% nie ma w tej regule - każdy z bloków trafia do obszaru w kolumnie 80% siatki i wypełnia ją całą. Dopisanie tu width: 80% dałoby 80% z 80%, czyli 64% okna. Trzy krótkie reguły z grid-area przypisują bloki do obszarów mapy.
Typowe błędy
box-shadow to cień całego prostokąta, a arkusz mówi o cieniu tekstu - text-shadow.
Dodatkowo dla bloku nawigacyjnego: margines wewnętrzny górny 10 px.
padding-top: 10px w regule nav, która już istnieje - tylko górny, jak w arkuszu. Wiersz siatki z nawigacją ma przez to 60 px wysokości (50 + 10), co razem z 50 + 450 + 50 daje dokładnie 610 px - tyle, ile blok boczny.
Typowe błędy
padding: 10px ze wszystkich stron zmienia wymiary bloku - arkusz mówi „jedynie górny” (R.4.7).
R.3.1 Układ bloków po uruchomieniu strony w przeglądarce jest zgodny z ilustracją 3 w arkuszu egzaminacyjnym (prawidłowo zastosowane właściwości CSS decydujące o układzie bloków na stronie, np. float i clear albo display flex albo grid)
R.4.8 Ustawione dla bloku nagłówkowego, stopki i bloku nawigacyjnego cień text-shadow: 4px 4px DimGray oraz dla bloku głównego paski przewijania auto
ok. 2 min
Polecenie z arkusza
Dla bloku głównego: kolor tła Thistle, szerokość 80%, wysokość 450 px, paski przewijania dodawane tylko, gdy zawartość nie mieści się w bloku.
grid-area: main, tło Thistle ze zmiennej, wysokość 450 px i overflow: auto - pasek pojawi się dopiero, gdy lista przerośnie blok. Szerokość 80% daje kolumna siatki. Wszystkie bloki stoją teraz tak jak na ilustracji 3: blok boczny po lewej, cztery bloki jeden pod drugim po prawej (R.3.1). Cień tekstu trzech bloków i paski auto bloku głównego dają razem R.4.8.
R.4.2 Ustawiony kolor tła MediumPurple dla bloków: nagłówkowego, stopki, nawigacyjnego i jedynie dla przycisków w liście (id jest błędem) oraz Thistle dla bloku głównego
R.4.3 Ustawiony biały kolor czcionki dla bloku nagłówkowego, stopki, bloku nawigacyjnego i przycisków
R.4.4 Ustawiona wysokość bloku bocznego i obrazu 610px, bloku nagłówkowego, stopki i bloku nawigacyjnego 50px, głównego 450px, dla przycisków 30px
ok. 2 min
Polecenie z arkusza
Dla przycisków w liście: opływanie do prawej strony, kolor tła MediumPurple, biały kolor czcionki, wysokość 30 px, bez obramowania.
Selektor potomka li button - tylko przyciski w elementach listy, przycisk „Dodaj” zostaje domyślny (klucz R.4.2: „jedynie dla przycisków w liście”, id byłoby błędem).
„Opływanie do prawej” to float: right - arkusz nazywa tu konkretną właściwość, więc zostaje, choć układ strony obywa się bez float. Do jednego przycisku przy tekście float nadaje się zresztą dobrze: tekst zostaje po lewej, przycisk dosuwa się do prawej krawędzi.
Z tym krokiem komplet są tła MediumPurple i Thistle (R.4.2), biały tekst bloków i przycisków (R.4.3) oraz wysokości 610 / 50 / 450 / 30 px (R.4.4).
R.4.5 Ustawiona szerokość bloku bocznego 20%, obrazu 100%, pozostałych bloków 80% oraz dla listy punktowanej 70% (width lub grid-template-columns lub flex)
R.4.9 Ustawione pozostałe cechy listy: rozmiar czcionki 25px, obramowanie 2px solid MediumPurple, brak znaków punktora, oraz dla przycisków: brak obramowania
ok. 2 min
Polecenie z arkusza
Dla listy punktowanej: marginesy zewnętrzne górny i dolny 40 px, lewy i prawy automatycznie wyliczane przez przeglądarkę, szerokość 70%, rozmiar czcionki 25 px, obramowanie linią ciągłą o szerokości 2 px i kolorze MediumPurple, lista nie ma znaków punktora.
margin: 40px auto - 40 px góra i dół, auto po bokach (przy ustalonej szerokości to wyśrodkowanie), szerokość 70% (ostatnia szerokość z R.4.5), czcionka 25 px, ramka i list-style-type: none - razem z przyciskami bez obramowania to R.4.9.
Typowe błędy
margin: 40px (jedna wartość) daje 40 px ze wszystkich stron i lista nie jest wyśrodkowana.
R.4.7 Ustawione marginesy wewnętrzne (padding) dla elementu listy - 10px, dla bloku nawigacyjnego - jedynie górny 10px oraz marginesy zewnętrzne (margin) dla listy - górny i dolny 40px, lewy i prawy - auto
ok. 1 min
Polecenie z arkusza
Dla elementu listy: marginesy wewnętrzne 10 px.
padding: 10px - tekst nie klei się do ramki. Teraz komplet marginesów z R.4.7: 10 px w elementach listy, górne 10 px nawigacji i 40 px / auto listy.
R.4.10 Gdy kursor znajduje się na elemencie listy, jego kolor tła zmienia się na Lavender oraz jedynie parzyste elementy listy mają kolor tła #DDCADD
ok. 1 min
Polecenie z arkusza
Gdy kursor znajduje się na elemencie listy, jego kolor tła zmienia się na Lavender.
li:hoverpo regule parzystych - ta sama specyficzność, więc wygrywa późniejsza i pod kursorem zmieniają kolor także parzyste elementy (R.4.10 ocenia obie reguły razem).
Kroki 27-32 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 27: Plik script.js z defer i klasa .done
Kryteria:
R.5.1 Skrypt zapisany w języku JavaScript i zawiera on przynajmniej jedną instrukcję zapisaną zgodnie ze składnią
ok. 3 min
Polecenie z arkusza
Napisany w języku JavaScript i działający na liście punktowanej.
Trzy rzeczy na start:
<script src="script.js" defer> w <head> - atrybut defer każe pobrać skrypt od razu, a uruchomić po wczytaniu całego HTML. Lista już istnieje, gdy skrypt jej szuka, a skrypt nie wstrzymuje rysowania strony,
w styl.css klasa .done z text-decoration: line-through - skrypt nie będzie wpisywał stylu, tylko dokładał klasę. Wygląd zostaje w pliku stylów (arkusz: „styl CSS zdefiniowany w całości w zewnętrznym pliku”), a skrypt mówi tylko, że zadanie jest wykonane,
pierwsza linia skryptu: const taskList = document.querySelector('#task-list') - lista wyszukana raz i zapamiętana w stałej. querySelector (tabela 1 arkusza) przyjmuje dowolny selektor CSS.
Krok 28: Przekreślenie zadania: jeden nasłuchiwacz na całej liście
Kryteria: ,
R.3.5 Po wciśnięciu przynajmniej jednego przycisku Wykonane jest wywoływana funkcja skryptu
R.5.5 Po wybraniu przycisku w liście tylko skojarzony z nim tekst jest przekreślany niezależnie od kolejności wciskanych przycisków. Sprawdzić jedynie dla wpisów ze stanu początkowego aplikacji
ok. 4 min
Polecenie z arkusza
Działanie funkcji wywoływanej po wciśnięciu dowolnego z przycisków „Wykonane”: przekreśla treść elementu listy związanego z tym przyciskiem.
Zamiast sześciu nasłuchiwaczy - jeden, na liście (delegacja zdarzeń). Kliknięcie w przycisk „wędruje” w górę drzewa dokumentu do <ul>, więc lista dowiaduje się o każdym kliknięciu w swoim wnętrzu:
event.target to element, w który kliknięto; .closest('button') szuka najbliższego przycisku (sam element albo jego przodek). Kliknięcie w tekst zadania, a nie w przycisk, daje null i funkcja kończy się na return,
button.closest('li') - element listy z tym przyciskiem, czyli „związany z tym przyciskiem”; classList.add('done') dokłada mu klasę przekreślenia.
Działa niezależnie od kolejności klikania (R.5.5) i - co najważniejsze - także dla zadań, które dopiero zostaną dodane, bo nasłuchuje lista, a nie przyciski. Kliknij „Wykonane” w podglądzie. Sam przycisk nie jest przekreślony: jako element pływający (float) nie dziedziczy dekoracji tekstu.
Typowe błędy
event.target.parentElement bez sprawdzenia, czy kliknięto przycisk, przekreśli całą listę <ul>... albo <main> - zależnie od tego, gdzie trafi kursor. closest z warunkiem chroni przed tym.
Krok 29: Funkcja dla przycisku „Dodaj”: obsługa wysłania formularza
Kryteria:
R.3.4 Po wciśnięciu przycisku Dodaj jest wywoływana funkcja skryptu
ok. 2 min
Polecenie z arkusza
Przycisk „Dodaj”, którego wciśnięcie powoduje wywołanie funkcji w skrypcie.
Formularz i pole też trafiają do stałych. Nasłuchiwacz nasłuchuje zdarzenia submit formularza, a nie click przycisku - submit przychodzi i po kliknięciu „Dodaj”, i po Enterze w polu. Pierwsza instrukcja event.preventDefault() wyłącza domyślne zachowanie formularza (przeładowanie strony), bo zadanie ma się pojawić bez przeładowania.
Klucz R.3.4 sprawdza, że wciśnięcie „Dodaj” wywołuje funkcję skryptu - wciśnięcie przycisku type="submit" wysyła formularz, a to wywołuje addTask.
Typowe błędy
Bez preventDefault() formularz bez action przeładuje stronę: nowe zadanie mignie i zniknie razem z przekreśleniami.
R.5.7 W skryptach zastosowana przynajmniej jedna zmienna oraz nazwy wszystkich zmiennych są w języku polskim lub angielskim i odzwierciedlają cel zastosowania
ok. 3 min
Polecenie z arkusza
Działanie funkcji wywoływanej po wciśnięciu przycisku „Dodaj”: tworzy nowy element listy na jej końcu. Element składa się z treści pobranej z pola edycyjnego.
taskInput.value.trim() - tekst z pola bez spacji na brzegach; pusty tekst kończy funkcję (required w HTML już to blokuje, ale skrypt nie powinien zależeć od atrybutu, który ktoś może usunąć),
document.createElement('li') - nowy element (tabela 3 arkusza),
item.append(\${text} `)-appenddokłada do elementu **tekst** (albo inne elementy). Tekst wstawiony w ten sposób zawsze jest tekstem: wpisane` pokaże się dosłownie, a nie jako pogrubienie. Szablon tekstowy w odwrotnych apostrofach skleja treść ze spacją przed przyciskiem.
Typowe błędy
item.innerHTML = text potraktowałby wpis użytkownika jak kod HTML - dla tekstu od użytkownika zawsze textContent albo append.
Krok 31: Dodawanie: przycisk „Wykonane” w nowym elemencie
Kryteria: ,
R.5.3 Funkcja dodająca wyświetla w ostatnim elemencie listy przycisk
R.5.4 Utworzony przycisk o nazwie Wykonane jest formatowany tak samo jak pozostałe przyciski w liście
ok. 3 min
Polecenie z arkusza
Przycisku o treści „Wykonane”, który jest formatowany tak jak reszta przycisków w liście i jego kliknięcie powoduje wywołanie odpowiedniej funkcji.
Nowy <button> z textContent = 'Wykonane' (textContent ustawia sam tekst i - inaczej niż innerText - nie każe przeglądarce przeliczać układu strony). item.append(tekst, button) wkłada tekst i przycisk do elementu w jednej instrukcji.
Przycisk nie dostaje żadnego nasłuchiwacza: kliknięcie dotrze do listy, a tam czeka markDone z delegacji (R.5.6). Formatowanie „jak reszta przycisków” daje reguła li button (R.5.4).
R.5.2 Po wybraniu przycisku dodającego jest wyświetlany tekst, który został pobrany z pola edycyjnego, jako ostatni element listy
R.5.6 Po dodaniu nowego elementu listy i wciśnięciu skojarzonego z nim przycisku, nowy element listy jest przekreślany
ok. 2 min
Polecenie z arkusza
Tworzy nowy element listy na jej końcu.
taskList.append(item) dokłada element jako ostatnie dziecko listy - na jej końcu (R.5.2). Potem taskForm.reset() czyści pole, a taskInput.focus() wraca do niego kursorem, żeby od razu wpisać kolejne zadanie.
Podgląd działa jak na ilustracji 4: wpisz „Lekarz”, Enter albo „Dodaj”, potem „Wykonane” przy nowym zadaniu - przekreśli się, choć w chwili rejestrowania nasłuchiwacza tego przycisku nie było (R.5.6).
Krok 33 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 33: Co jest inaczej i którą wersję wybrać
ok. 3 min
Polecenie z arkusza
Dla uproszczenia należy założyć, że w stanie początkowym jest 6 elementów listy, elementy mogą być dodawane, ale nie są usuwane.
wersja podstawowa
ta wersja
układ
float: left na pięciu blokach
grid-template-areas - mapa układu w kodzie
szerokości 20% / 80%
width w każdej regule
grid-template-columns
przekreślenie
style.textDecoration ze skryptu
klasa .done w CSS
przyciski „Wykonane”
onclick="markDone(this)" i setAttribute
jeden nasłuchiwacz na liście
„Dodaj”
onclick przycisku
zdarzenie submit formularza (działa też Enter)
Arkusz upraszcza: elementy nie są usuwane. Gdyby były, delegacja zdarzeń nie wymagałaby żadnych zmian, a w wersji z nasłuchiwaczem przy każdym przycisku trzeba by pamiętać o każdym nowym i usuniętym elemencie.
Na egzaminie: wersja podstawowa trzyma się podpowiedzi z tabeli 1 (onclick, setAttribute) i jest szybsza do napisania bez dokumentacji. Ta wymaga pewności co do closest, classList i grid-template-areas - jeśli to pisze się z pamięci, kodu jest podobnie dużo, a strona lepiej się zachowuje (Enter, puste zadanie, zadania dodane później).
Krok 34 · po tym etapie masz 37 z 37 kryteriów (pkt)
Krok 34: 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. Nagraj płytę z rezultatami pracy.
Na płycie, w folderze z numerem zdającego: import.png, kw1.jpg - kw4.jpg, kwerendy.txt, notatki.html, obraz.jpg, przeglądarka.txt, styl.css i script.js. Po nagraniu sprawdź odczyt płyty.
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.