javascript mini project | java php laravel linux mysql sql bootstrap html css query java php laravel linux mysql sql bootstrap html css query: javascript mini project

Saturday, April 18, 2026

javascript mini project

📚 Seri Belajar JavaScript — Artikel 14 dari 14

Proyek Mini: Bangun Aplikasi Web Interaktif dari Nol dengan Pure JavaScript

Saatnya semua ilmu yang kamu pelajari selama 13 artikel ini berpadu jadi satu — sebuah aplikasi nyata yang bisa kamu bangga-banggain ke teman-teman!

#JavaScript #ProyekPemula #WebInteraktif #PureJS #HTML5
⏱️
Estimasi Baca
12 Menit
🎯
Level
Pemula → Intermediate
📅
Tahun
2026

Pernah nggak kamu belajar banyak hal — teori, konsep, latihan kecil-kecilan — tapi pas ditanya "kamu bisa bikin apa?" kamu malah bingung sendiri? Nah, itulah momen di mana sebuah proyek JavaScript aplikasi web interaktif pemula menjadi senjata paling ampuh. Bukan buat gagah-gagahan, tapi karena satu proyek nyata bisa mengunci ratusan konsep sekaligus ke dalam otakmu.

Di artikel terakhir dari Seri Belajar JavaScript from Zero to Zorro ini, kamu akan membangun sebuah aplikasi Task Manager (To-Do App) yang benar-benar interaktif — dengan fitur tambah tugas, tandai selesai, hapus, filter status, dan simpan data ke localStorage. Semuanya dari nol, tanpa framework, murni Pure JavaScript. Siap?

Mengapa Proyek Mini Adalah Cara Terbaik Belajar JavaScript?

Bayangkan kamu belajar cara mengendarai motor hanya dari buku. Kamu tahu teorinya: gas di kanan, rem di kiri, setang buat belok. Tapi pas pertama kali naik motor sungguhan, tetap saja oleng, kan? Belajar JavaScript tanpa proyek nyata persis seperti itu — semua terasa jelas di kepala, tapi tangan kamu belum pernah "merasakan" bagaimana kode bekerja bersama.

Proyek mini memaksa kamu menggabungkan banyak konsep sekaligus: DOM manipulation, event listener, array, localStorage, dan logika kondisional — semuanya berinteraksi dalam satu ekosistem kode yang utuh.

🧩 Formula Belajar

Teori × Latihan Kecil × Proyek Nyata = Pemahaman yang Bertahan

Tanpa salah satu elemen ini, kamu hanya "merasa" sudah bisa — bukan benar-benar bisa. Proyek adalah ujian sesungguhnya.

🔥
Fakta Menarik

Riset dari freeCodeCamp menunjukkan bahwa developer yang menyelesaikan minimal satu proyek nyata dalam proses belajarnya 3× lebih cepat mendapat pekerjaan dibanding yang hanya mengikuti tutorial tanpa proyek.

Jadi, kalau selama ini kamu sudah baca 13 artikel dalam seri ini — mulai dari variabel, DOM, event, localStorage, sampai Fetch API — anggap artikel ini sebagai "final exam" yang paling menyenangkan yang pernah kamu hadapi. Tidak ada soal pilihan ganda. Hanya kode dan hasil nyata di browser.

Proyek JavaScript Pemula: Membangun Task Manager Interaktif Step by Step

Kita akan membangun Task Manager — sebuah aplikasi web interaktif yang memungkinkan pengguna mencatat tugas, menandainya selesai, menghapusnya, dan menyimpan semua data di browser tanpa server. Inilah fitur-fitur yang akan kita buat:

Fitur Konsep JavaScript yang Dipakai Artikel Ref.
➕ Tambah Tugas DOM Manipulation, Event Listener, Array 6, 7, 5
✅ Tandai Selesai Toggle class CSS, manipulasi object 9, 5
🗑️ Hapus Tugas Array filter, re-render DOM 5, 6
🔍 Filter Status Array filter, conditional rendering 3, 5
💾 Simpan ke Browser localStorage, JSON.stringify/parse 10
💡
Tips Sebelum Mulai

Buat satu folder baru bernama task-manager, lalu buat tiga file: index.html, style.css, dan app.js. Kode di bawah akan kita bagi ke masing-masing file.

1

Struktur HTML Dasar

Buka index.html dan tulis kerangka aplikasinya. Ini adalah "tulang" dari UI kita — form input di atas, filter di tengah, dan daftar tugas di bawah.

index.html 📄
<!DOCTYPE html>
<html lang="id">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Task Manager - Proyek JS Pemula</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <h1>📋 Task Manager</h1>

    <!-- Form tambah tugas -->
    <div class="input-area">
      <input type="text" id="taskInput" placeholder="Tulis tugasmu di sini...">
      <button id="addBtn">Tambah</button>
    </div>

    <!-- Filter tombol -->
    <div class="filter-area">
      <button class="filter-btn active" data-filter="all">Semua</button>
      <button class="filter-btn" data-filter="active">Aktif</button>
      <button class="filter-btn" data-filter="done">Selesai</button>
    </div>

    <!-- Daftar tugas -->
    <ul id="taskList"></ul>

    <!-- Info jumlah tugas -->
    <p id="taskCount"></p>
  </div>

  <script src="app.js"></script>
</body>
</html>
2

CSS Tampilan (style.css)

Desain sederhana tapi clean — dark mode ringan dengan aksen biru indigo. Kamu bebas memodifikasinya sesuai selera.

style.css 🎨
* { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: 'Segoe UI', sans-serif;
  background: #f1f5f9;
  min-height: 100vh;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
}

.container {
  background: white;
  border-radius: 16px;
  padding: 32px;
  width: 100%;
  max-width: 520px;
  box-shadow: 0 8px 40px rgba(0,0,0,0.1);
}

h1 { 
  font-size: 26px; color: #1e1b4b; margin-bottom: 24px; 
}

.input-area { display: flex; gap: 10px; margin-bottom: 16px; }

.input-area input {
  flex: 1; padding: 12px 16px; border: 2px solid #e2e8f0;
  border-radius: 10px; font-size: 15px; outline: none;
  transition: border-color 0.2s;
}
.input-area input:focus { border-color: #6366f1; }

.input-area button, .filter-btn {
  background: #6366f1; color: white; border: none;
  padding: 12px 20px; border-radius: 10px; cursor: pointer;
  font-size: 15px; font-weight: 600; transition: background 0.2s;
}
.input-area button:hover { background: #4f46e5; }

.filter-area { display: flex; gap: 8px; margin-bottom: 20px; }
.filter-btn { 
  background: #e2e8f0; color: #64748b; padding: 8px 16px; 
  font-size: 14px; border-radius: 8px;
}
.filter-btn.active { background: #6366f1; color: white; }
.filter-btn:hover { background: #6366f1; color: white; }

#taskList { list-style: none; display: flex; flex-direction: column; gap: 10px; }

.task-item {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px; border: 1px solid #e2e8f0;
  border-radius: 10px; transition: all 0.2s;
}
.task-item:hover { border-color: #6366f1; }
.task-item.done { background: #f0fdf4; border-color: #86efac; }
.task-item.done span { text-decoration: line-through; color: #94a3b8; }

.task-item input[type="checkbox"] { 
  width: 18px; height: 18px; cursor: pointer; accent-color: #6366f1;
}
.task-item span { flex: 1; font-size: 15px; color: #334155; }
.task-item .del-btn {
  background: none; border: none; cursor: pointer;
  font-size: 18px; padding: 2px 6px; border-radius: 6px;
  transition: background 0.15s;
}
.task-item .del-btn:hover { background: #fee2e2; }

#taskCount { 
  margin-top: 16px; font-size: 13px; color: #94a3b8; text-align: right; 
}
3

JavaScript Utama (app.js)

Ini jantungnya. Kita simpan semua tugas dalam sebuah array of objects, lalu render ulang daftar setiap kali ada perubahan — pola ini disebut state-driven rendering, teknik dasar yang juga dipakai React dan Vue!

app.js ⚙️
// ── State: array semua tugas ──────────────────────
let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
let currentFilter = 'all';

// ── Simpan ke localStorage ────────────────────────
function saveTasks() {
  localStorage.setItem('tasks', JSON.stringify(tasks));
}

// ── Render daftar tugas ke DOM ────────────────────
function renderTasks() {
  const list = document.getElementById('taskList');
  const countEl = document.getElementById('taskCount');

  // Filter tugas sesuai pilihan
  let filtered = tasks;
  if (currentFilter === 'active') {
    filtered = tasks.filter(t => !t.done);
  } else if (currentFilter === 'done') {
    filtered = tasks.filter(t => t.done);
  }

  // Kosongkan list dulu, lalu isi ulang
  list.innerHTML = '';

  filtered.forEach(task => {
    const li = document.createElement('li');
    li.className = 'task-item' + (task.done ? ' done' : '');

    li.innerHTML = `
      <input type="checkbox" ${task.done ? 'checked' : ''} 
             onchange="toggleTask('${task.id}')">
      <span>${task.text}</span>
      <button class="del-btn" onclick="deleteTask('${task.id}')">🗑️</button>
    `;
    list.appendChild(li);
  });

  // Update info jumlah
  const total = tasks.length;
  const done = tasks.filter(t => t.done).length;
  countEl.textContent = `${done} dari ${total} tugas selesai`;
}

// ── Tambah tugas baru ─────────────────────────────
function addTask() {
  const input = document.getElementById('taskInput');
  const text = input.value.trim();

  if (!text) {
    alert('Tulis dulu tugasnya, bos! 😄');
    return;
  }

  const newTask = {
    id: Date.now().toString(), // ID unik pakai timestamp
    text: text,
    done: false
  };

  tasks.push(newTask);
  saveTasks();
  renderTasks();

  input.value = ''; // Kosongkan input
  input.focus();
}

// ── Toggle selesai / belum ────────────────────────
function toggleTask(id) {
  tasks = tasks.map(t =>
    t.id === id ? { ...t, done: !t.done } : t
  );
  saveTasks();
  renderTasks();
}

// ── Hapus tugas ───────────────────────────────────
function deleteTask(id) {
  tasks = tasks.filter(t => t.id !== id);
  saveTasks();
  renderTasks();
}

// ── Event: tombol Tambah & Enter ──────────────────
document.getElementById('addBtn').addEventListener('click', addTask);
document.getElementById('taskInput').addEventListener('keydown', e => {
  if (e.key === 'Enter') addTask();
});

// ── Event: tombol Filter ──────────────────────────
document.querySelectorAll('.filter-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    currentFilter = btn.dataset.filter;
    document.querySelectorAll('.filter-btn')
            .forEach(b => b.classList.remove('active'));
    btn.classList.add('active');
    renderTasks();
  });
});

// ── Jalankan render saat halaman pertama dibuka ───
renderTasks();
4

Buka di Browser & Uji Coba

Klik dua kali index.html untuk membukanya di browser. Coba tambah beberapa tugas, centang salah satunya, filter, lalu refresh halaman — datamu masih ada! Itulah keajaiban localStorage yang sudah kamu pelajari di Artikel 10. 🎉

Bedah Kode: Konsep Kunci di Balik Aplikasi Web Interaktif Ini

Jangan cuma copy-paste! Pastikan kamu paham kenapa kodenya ditulis seperti itu. Mari kita bedah tiga pola terpenting yang kamu akan terus pakai bahkan setelah belajar React atau Vue sekalipun.

🔬 Analisis Pola Kode
🗄️ Pola 1: Single Source of Truth

Semua data tugas disimpan HANYA di array tasks. DOM hanyalah "cermin" dari state ini. Setiap perubahan → ubah array → panggil renderTasks(). Pola ini membuat kode lebih mudah di-debug dan dikelola.

🆔 Pola 2: ID Unik dengan Date.now()

Date.now() menghasilkan angka timestamp dalam milidetik — hampir mustahil ada dua tugas dengan ID sama. Ini cara mudah membuat ID unik tanpa library tambahan.

🔁 Pola 3: Immutable Update dengan Map & Filter

Kita tidak mengubah elemen array secara langsung — kita membuat array baru menggunakan .map() (untuk update) dan .filter() (untuk hapus). Ini adalah prinsip immutability yang sangat dihargai di dunia JavaScript modern.

Insight Penting

Tiga pola di atas — single source of truth, unique ID, dan immutable update — bukan sekadar "cara lain". Ini adalah fondasi berpikir yang dipakai React, Vue, dan hampir semua framework JavaScript modern. Kamu baru saja belajar pondasi framework tanpa tahu ada framework!

⚠️
Perhatian

localStorage menyimpan data per domain dan per browser. Jika kamu membuka file HTML langsung (protokol file://), beberapa browser memblokir localStorage. Gunakan ekstensi Live Server di VS Code supaya berjalan di localhost.

Tantangan Lanjutan: Kembangkan Proyek JavaScript Interaktif-mu Lebih Jauh

Selesai? Keren! Tapi seorang developer sejati tidak pernah berhenti di "versi pertama". Berikut adalah beberapa ide tantangan yang bisa kamu coba sendiri — dari yang mudah hingga yang menantang:

🟢
Mudah — Edit Tugas

Tambahkan tombol ✏️ di setiap item. Saat diklik, ubah teks menjadi input yang bisa diedit. Simpan perubahan saat tekan Enter.

🟡
Menengah — Prioritas & Deadline

Tambahkan field prioritas (Tinggi/Sedang/Rendah) dan tanggal batas. Tampilkan badge warna berbeda. Urutkan berdasarkan prioritas.

🔴
Sulit — Sinkronisasi via Fetch API

Integrasikan dengan JSONPlaceholder atau buat backend Node.js sendiri. Simpan tugas ke server, bukan hanya localStorage. Gunakan async/await dari Artikel 11 dan Fetch API dari Artikel 12.

✅ Kesimpulan

Kamu Baru Saja Menyelesaikan Perjalanan Zero to Zorro!

Dari mengenal variabel di Artikel 1 hingga membangun proyek JavaScript aplikasi web interaktif pemula yang sesungguhnya di artikel terakhir ini — kamu sudah menempuh perjalanan yang luar biasa. Ingat poin-poin kuncinya:

  • Satu proyek nyata lebih berharga dari seratus tutorial tanpa praktek
  • Pola state-driven rendering yang kamu pakai hari ini adalah fondasi React dan Vue
  • localStorage, DOM manipulation, event listener, dan array — semuanya berpadu dalam satu kode
  • Langkah selanjutnya: perluas proyeknya, atau mulai belajar framework seperti React!
📚 Lihat Semua Artikel Seri 💬 Bagikan proyekmu di komentar!

📢 Kalau artikel ini membantumu, share ke teman yang juga lagi belajar JavaScript. Atau tinggalkan komentar — tugas pertama apa yang kamu tambahkan di Task Manager-mu? 😄

#JavaScript #ProyekMini #WebInteraktif #PureJavaScript #BelajarJS #TodoApp #LocalStorage #Pemula
🗂️ Semua Artikel dalam Seri Ini
01 Kenalan dengan JavaScript: Cara Kerja, Posisi di Web, dan Script Pertamamu 02 Variabel, Tipe Data, dan Operator: Pondasi Logika JavaScript 03 Kontrol Alur Program: if, else, switch, dan Perulangan Loop 04 Fungsi JavaScript: Cara Buat, Pakai, dan Sederhanakan Kode Kamu 05 Array dan Object: Menyimpan Banyak Data dengan Rapi 06 DOM: Cara JavaScript Mengontrol Elemen HTML di Halaman Web 07 Event & Interaksi: Buat Halaman Web yang Merespons Aksi Pengguna 08 Manipulasi Form: Ambil, Validasi, dan Tampilkan Data Input Pengguna 09 Manipulasi CSS dengan JavaScript: Animasi & Tampilan Dinamis Tanpa Plugin 10 localStorage & sessionStorage: Simpan Data di Browser Tanpa Server 11 Asynchronous JavaScript: Callback, Promise, dan async/await 12 Fetch API & AJAX: Ambil Data dari Internet Langsung ke Halaman Web 13 JavaScript Modular: Pisahkan Kode Besar Menjadi File yang Terorganisir
14 📍 Proyek Mini: Bangun Aplikasi Web Interaktif dari Nol (Kamu di sini!)
🧭 Navigasi Seri
← Artikel Sebelumnya
ARTIKEL 13
JavaScript Modular: Pisahkan Kode Besar Menjadi File yang Terorganisir
🏆
Selamat!
Ini adalah artikel terakhir

Kamu sudah menyelesaikan seluruh seri Zero to Zorro! 🎉

No comments:

Post a Comment

saifiahmada.com adalah blog belajar programming Indonesia, membahas lengkap materi bahasa pemrograman: code HTML, CSS, Bootstrap, Desain, PHP, MySQL, coding Java, Query, SQL, dan dunia linux