Ilustrasi mini project HTML

Mini Project 5
Membuat Daftar Tugas yang Bisa Dipakai

oleh: Suryo Adhy Chandra, ST

Mini project ini menggabungkan hampir semua yang sudah dipelajari: struktur HTML, penataan dengan Flexbox, serta JavaScript untuk DOM dan event. Hasil akhirnya adalah daftar tugas sederhana yang benar-benar bisa dipakai, lengkap dengan menambah, menandai selesai, dan menghapus tugas.

Kerjakan bertahap dan jalankan setiap selesai satu tahap. Menumpuk banyak kode lalu menjalankannya sekaligus adalah cara tercepat untuk bingung ketika ada yang salah.

Tahap 1 — Menyiapkan rangka HTML

Buat satu berkas bernama tugas.html. Perhatikan bahwa kita memakai elemen form, bukan sekadar tombol, agar pengguna bisa menekan Enter untuk menambah.

<!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Daftar Tugas</title> </head> <body> <div class="wadah"> <h1>Daftar Tugas</h1> <form id="form-tugas"> <input type="text" id="isi-tugas" placeholder="Tulis tugas baru"> <button type="submit">Tambah</button> </form> <p id="pesan"></p> <ul id="daftar-tugas"></ul> <p id="ringkasan"></p> </div> <script src="tugas.js"></script> </body> </html>
Tag script sengaja diletakkan sebelum penutup body, bukan di dalam head. Kalau ditaruh di head, JavaScript akan berjalan sebelum elemen-elemennya ada, dan pencarian elemen akan menghasilkan null.

Tahap 2 — Menata tampilan dengan Flexbox

Tambahkan berkas tugas.css lalu sambungkan lewat tag link di head. Flexbox dipakai dua kali di sini: untuk menyejajarkan kolom dengan tombol, dan untuk merapikan tiap baris tugas.

body { font-family: system-ui, sans-serif; background: #f1f5f9; padding: 24px; } .wadah { max-width: 520px; margin: 0 auto; background: #ffffff; border-radius: 12px; padding: 24px; } #form-tugas { display: flex; gap: 8px; margin-bottom: 16px; } #isi-tugas { flex: 1 1 auto; /* kolom melebar mengisi ruang sisa */ padding: 10px 12px; } #daftar-tugas { list-style: none; padding: 0; } #daftar-tugas li { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px 12px; border-bottom: 1px solid #e2e8f0; } .selesai { text-decoration: line-through; color: #94a3b8; }

Perhatikan flex: 1 1 auto pada kolom masukan. Itu yang membuat kolomnya melebar mengikuti lebar layar sementara tombolnya tetap seukuran isinya, tanpa perlu menghitung lebar apa pun.

Tahap 3 — Menambah tugas

Buat berkas tugas.js. Mulai dari bagian paling dasar dulu: menambahkan satu baris ke daftar.

const form = document.querySelector("#form-tugas"); const kolom = document.querySelector("#isi-tugas"); const daftar = document.querySelector("#daftar-tugas"); const pesan = document.querySelector("#pesan"); form.addEventListener("submit", function (event) { event.preventDefault(); const isi = kolom.value.trim(); if (isi === "") { pesan.textContent = "Tugas tidak boleh kosong"; return; } pesan.textContent = ""; tambahTugas(isi); kolom.value = ""; kolom.focus(); }); function tambahTugas(isi) { const item = document.createElement("li"); const teks = document.createElement("span"); teks.textContent = isi; item.appendChild(teks); daftar.appendChild(item); }
Perintah kolom.focus() mengembalikan kursor ke kolom masukan setelah tugas ditambahkan. Detail kecil seperti ini yang membedakan aplikasi yang enak dipakai dari yang sekadar berfungsi.

Tahap 4 — Menandai selesai dan menghapus

Sekarang tambahkan dua tombol pada setiap baris. Ganti isi fungsi tambahTugas menjadi seperti ini:

function tambahTugas(isi) { const item = document.createElement("li"); const teks = document.createElement("span"); teks.textContent = isi; const tombolSelesai = document.createElement("button"); tombolSelesai.textContent = "Selesai"; tombolSelesai.addEventListener("click", function () { teks.classList.toggle("selesai"); perbaruiRingkasan(); }); const tombolHapus = document.createElement("button"); tombolHapus.textContent = "Hapus"; tombolHapus.addEventListener("click", function () { item.remove(); perbaruiRingkasan(); }); const aksi = document.createElement("div"); aksi.appendChild(tombolSelesai); aksi.appendChild(tombolHapus); item.appendChild(teks); item.appendChild(aksi); daftar.appendChild(item); perbaruiRingkasan(); }

Perhatikan bahwa penanganan klik dipasang saat baris itu dibuat, bukan sekali di awal program. Ini penting: baris yang belum ada tidak bisa dipasangi penanganan event.

Tahap 5 — Menampilkan ringkasan

const ringkasan = document.querySelector("#ringkasan"); function perbaruiRingkasan() { const semua = daftar.querySelectorAll("li").length; const selesai = daftar.querySelectorAll(".selesai").length; if (semua === 0) { ringkasan.textContent = "Belum ada tugas."; return; } ringkasan.textContent = selesai + " dari " + semua + " tugas selesai"; } perbaruiRingkasan(); // dipanggil sekali saat halaman dibuka

Kalau ada yang tidak berjalan

Pengembangan lanjutan

Satu catatan penting: daftar tugas ini hilang setiap kali halaman ditutup, karena datanya hanya ada di memori browser. Untuk menyimpannya secara permanen, diperlukan localStorage atau penyimpanan di sisi server, yang menjadi bahan pelajaran berikutnya.
← Kembali Ke Daftar Mini Project