Tutorial JavaScript: Menambahkan Fitur Coret Tugas Selesai pada To-Do List
Halo semua! Senang bisa kembali melanjutkan seri pembuatan aplikasi To-Do List kita. Di artikel sebelumnya, kita sudah berhasil membuat data tugas tersimpan aman di browser menggunakan LocalStorage (Baca: Tutorial JavaScript: Cara Menyimpan Data To-Do List ke LocalStorage Browser - Part 3)
Namun, sebuah aplikasi daftar tugas belum lengkap rasanya jika kita tidak bisa menandai tugas mana saja yang sudah selesai dikerjakan.
Oleh karena itu, di artikel bagian ke-4 ini kita akan menambahkan fitur coret/check-list tugas selesai (toggled completed).
Menariknya, status "selesai" atau "belum selesai" ini juga akan langsung tersimpan secara permanen di LocalStorage!
Konsep Perubahan Struktur Data
Sebelumnya, kita hanya menyimpan teks tugas berupa string biasa di dalam array, contohnya: ["Belajar JavaScript", "Beli Kopi"].
Agar bisa menyimpan status pengerjaan, kita harus mengubah string tersebut menjadi sebuah Object yang memiliki dua properti: text (untuk nama tugas) dan completed (berupa nilai boolean true atau false). Untuk contoh strukturnya menjadi seperti dibawah ini:
Loading...
[
{ text: "Belajar JavaScript", completed: false },
{ text: "Beli Kopi", completed: true }
]1. Memperbarui File CSS (style.css)
Pertama, buka file style.css kamu. Kita perlu menambahkan satu class baru bernama .completed. Class ini berfungsi untuk memberikan efek coret tengah (line-through) dan mengubah warna teks menjadi agak buram ketika tugas selesai.
Tambahkan kode CSS dibawah ini di bagian paling bawah file CSS kamu:
Loading...
/* Efek teks coret untuk tugas yang sudah selesai */
li.completed {
text-decoration: line-through;
color: #888888;
background-color: #f1f1f1;
}
/* Mengubah kursor menjadi pointer saat mengklik baris tugas */
li {
cursor: pointer;
user-select: none; /* Mencegah teks terblok saat diklik berulang kali */
}2. Memperbarui File JavaScript (script.js)
Selanjutnya, kita akan merombak logika di file script.js. Kita akan mengubah cara memasukkan data ke array, menambahkan fungsi untuk mengubah status (toggle), dan memperbarui fungsi render agar mendeteksi class .completed di atas.
Silakan ganti seluruh isi file script.js kamu dengan kode terbaru berikut ini:
Loading...
// 1. Ambil elemen HTML yang dibutuhkan
const taskInput = document.getElementById('taskInput');
const addBtn = document.getElementById('addBtn');
const taskList = document.getElementById('taskList');
// 2. Ambil data dari LocalStorage (Data sekarang berbentuk Array of Objects)
let tasks = JSON.parse(localStorage.getItem('myTasksWithStatus')) || [];
// 3. Fungsi untuk menampilkan (render) semua tugas ke layar
function renderTasks() {
taskList.innerHTML = "";
tasks.forEach((task, index) => {
const li = document.createElement('li');
li.textContent = task.text;
// Cek jika status tugas adalah selesai (true), tambahkan class 'completed'
if (task.completed) {
li.classList.add('completed');
}
// Fitur Toggle: Klik pada baris tugas untuk menandai selesai/belum selesai
li.addEventListener('click', function(event) {
// Pastikan yang diklik adalah baris teksnya, bukan tombol hapus
if (event.target.tagName !== 'BUTTON') {
toggleTask(index);
}
});
// Buat tombol hapus
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Hapus';
deleteBtn.className = 'delete-btn';
deleteBtn.onclick = function() {
deleteTask(index);
};
li.appendChild(deleteBtn);
taskList.appendChild(li);
});
}
// 4. Fungsi untuk menambah tugas baru (sebagai Object)
function addTask() {
const taskText = taskInput.value.trim();
if (taskText === "") {
alert("Silakan tulis tugas terlebih dahulu!");
return;
}
// Masukkan data baru berupa Object ke dalam array
tasks.push({
text: taskText,
completed: false // Default tugas baru selalu belum selesai
});
saveToLocalStorage();
renderTasks();
taskInput.value = "";
taskInput.focus();
}
// 5. Fungsi untuk mengubah status selesai/belum selesai (Toggle)
function toggleTask(index) {
// Balikkan nilai boolean (jika true jadi false, jika false jadi true)
tasks[index].completed = !tasks[index].completed;
saveToLocalStorage();
renderTasks();
}
// 6. Fungsi untuk menghapus tugas
function deleteTask(index) {
tasks.splice(index, 1);
saveToLocalStorage();
renderTasks();
}
// 7. Fungsi pembantu untuk menyimpan data ke LocalStorage
function saveToLocalStorage() {
localStorage.setItem('myTasksWithStatus', JSON.stringify(tasks));
}
// 8. Event Listeners
addBtn.addEventListener('click', addTask);
taskInput.addEventListener('keypress', function(event) {
if (event.key === 'Enter') {
addTask();
}
});
// Jalankan fungsi render pertama kali saat halaman dibuka
renderTasks();Penjelasan Logika Kode Baru
- tasks[index].completed = !tasks[index].completed Tanda seru (!) di JavaScript adalah operator NOT. Kode ini berfungsi membalikkan nilai boolean. Jika awalnya false (belum selesai), kode ini mengubahnya menjadi true (selesai), begitu juga sebaliknya.
- event.target.tagName !== 'BUTTON' Validasi ini sangat penting. Fungsinya untuk memastikan bahwa efek coret hanya aktif ketika pengguna mengklik teks tugas pada elemen <li>, bukan ketika pengguna mengklik tombol "Hapus".
- li.classList.add('completed') Jika properti completed bernilai true, JavaScript akan otomatis menempelkan class CSS .completed pada elemen daftar tersebut sehingga teks langsung tercoret.
Kesimpulan & Eksperimen Selanjutnya!
Selamat! Aplikasi To-Do List milikmu sekarang sudah memiliki fitur yang sangat lengkap. Pengguna bisa menambah tugas, menandai tugas yang selesai dengan efek coret, menghapus tugas, dan semua aktivitas tersebut tidak akan hilang meskipun browser dimuat ulang.
Sebagai proyek pengembangan mandiri berikutnya, kamu bisa mencoba menambahkan fitur filter (tombol untuk menampilkan "Semua Tugas", "Tugas yang Belum Selesai", atau "Tugas yang Sudah Selesai").
Sampai jumpa di tutorial menarik lainnya. Jika ada baris kode yang membingungkan, silakan koreksi ulang, dimana letak kesalahannya! Selamat belajar! 🚀








