Usuwamy zadania za pomocą przycisku
Czyścimy listę | Usuwamy wszystkie zadania
Skoro tak dobrze poszło nam przypisywanie funkcji do przycisków, zróbmy to samo w celu usuwania zadań. Zacznijmy od usunięcia wszystkich zadań na raz za pomocą przycisku wyczyść listę, ponieważ to będzie najłatwiejsze - mamy już gotową funkcję deleteAllTasks()
, której nie będziemy nawet modyfikować oraz wiemy, jak przypisać obsługę kliknięcia do elementu HTML. Zmodyfikujmy więc ostatnią linijkę w naszym kodzie HTML:
<!-- poprzedni kod HTML -->
<button onclick="deleteAllTasks()">wyczyść listę</button>
I to tyle! Zapisz plik HTML, otwórz go w przeglądarce, uruchom nasz plik JavaScript w zakładce snippets
oraz spróbuj teraz dodać kilka zadań (oczywiście za pomocą przycisku dodaj zadanie), po czym usuń je wszystkie na raz klikając w przycisk wyczyść listę. Nasze 2 (na razie jedyne) przyciski aplikacji działają!
Usuwamy pojedyncze zadania
Jeśli chodzi usunięcie pojedynczego zadania, to sprawa się trochę komplikuje. Przede wszystkim, zauważ, że nie mamy w ogóle przycisku/ów do usuwania poszczególnych zadań! W kursie HTML dodaliśmy taki przycisk do każdego statycznie wpisanego zadania, aczkolwiek później w tym kursie dynamicznie tworzymy nowe zadanie jako element listy, ale bez przycisku.
W związku z tym, musimy zmodyfikować funkcję appendTaskToTheTasksList()
w taki sposób, żeby tworząc element listy (zadanie) nie tylko wyświetliła zadanie, ale także wyrenderowała obok niego przycisk do usuwania tego zadania.
Zmodyfikuj funkcję appendTaskToTheTasksList()
zgodnie z poniższym kodem - wszelkie szczegóły są wyjaśnione w komentarzach:
// dodaj w nawiasach drugi argument - indeks zadania,
// byśmy mogli go przekazać do deleteTask(), która potrzebuje indeksu
// (pamiętaj, że appendTaskToTheTasksList() jest później przekazana do metody forEach,
// która przekaże 2 argumenty: task i index):
function appendTaskToTheTasksList(task, index) {
// utwórz nowy element listy li:
const li = document.createElement("li");
// i przypisz do niego wartość zadania:
//====================> ZMODYFIKOWANY KOD: ============================//
li.textContent = task + " "; // dodajemy spację, by oddzielić tekst od przycisku usuń
// utwórz przycisk usuwania zadania:
const deleteButton = document.createElement("button");
// przypisz do niego nazwę:
deleteButton.textContent = "usuń";
// przypisz do niego funkcję usuwania tego konkretnego zadania
// (to jest nasza istniejąca już funkcja deleteTask())
deleteButton.onclick = function() {
deleteTask(index);
}
// dodaj przycisk do nowego elementu listy
li.appendChild(deleteButton); // teraz przycisk będzie dodany po zadaniu po spacji
//================> KONIEC ZMODYFIKOWANEGO KODU =======================//
tasksList.appendChild(li);
}
Brawo! Teraz musimy przetestować usuwanie zadań!
W tym miejscu chciałbym dokładniej wyjaśnić, co się dzieje w tym framencie kodu powyższej zmodyfikowanej funkcji:
// ... kod funkcji appendTaskToTheTasksList()...
// przypisz do niego funkcję usuwania tego konkretnego zadania
// (to jest nasza istniejąca już funkcja deleteTask())
deleteButton.onclick = function() {
deleteTask(index);
}
// ...dalszy kod funkcji appendTaskToTheTasksList()...
W powyższym kodzie przypisaliśmy funkcję usuwania zadania do atrybutu onclick
, ale nie bezpośrednio w HTMLu, jak to robiliśmy wcześniej, tylko za pośrednictwem kodu JavaScript. deleteButton
jest zmienną reprezentującą przycisk, w związku z tym mamy dostęp także do atrybutów tego przycisku, tj. np. wspomniany onclick
. Po prostu przypisaliśmy do niego wartość w postaci funkcji.
Dlaczego natomiast użyliśmy słowa kluczowego function()
, a nie np. po prostu podaliśmy nazwę funkcji? Jest tak dlatego, że gdybyśmy przypisali funkcję z argumentem w ten sposób: deleteButton.onclick = deleteTask(index);
, to wyskoczy nam błąd podczas usuwania, ponieważ nie przypisaliśmy tak naprawdę funkcji, ile ją wywołaliśmy wraz z argumentem już w momencie przypisania!
Moglibyśmy z kolei poprawnie przypisać funkcję w ten sposób: deleteButton.onclick = deleteTask;
. Jak widzisz, nie ma nawiasów, w związku z tym nie ma błędu i można by było wywołać teraz tę przypisaną funkcję w ten sposób: deleteButton.onclick(index)
, tyle że nie jesteśmy w stanie tego zrobić, ponieważ deleteButton.onclick
zostanie wywołane z poziomu HTML i nie ma jak przekazać tam argumentu index
.
W związku z tym przypisaliśmy do deleteButton.onclick
deklarację funkcji anonimowej function(){}
(anonimowej, czyli nie posiadającej nazwy po słowie kluczowym function
), która z kolei wywołuje wewnątrz funkcję deleteTask(index)
w momencie, kiedy kliknie się w przycisk.
W nowoczesnym JavaScripcie moglibyśmy to także zrobić prościej, za pomocą funkcji strzałkowej (arrow function): deleteButton.onclick = () => deleteTask(index)
, aczkolwiek ten zapis również wymagałby wyjaśnienia, natomiast znamy się już na definiowaniu funkcji za pomocą słowa kluczowego function
, w związku z czym wybrałem tę opcję.