Amaliy loyiha 1 — To-do app

DarslarWeb dasturlash

Amaliy loyiha 1 — To-do app

Butun kursdan o'rgangan narsalarni birlashtirib, to'liq funksional to-do app yaratamiz.

70 daqiqa
JavaScript — Dars 19

Amaliy loyiha: To-do app

DOM, eventlar, massiv metodlari, class'lar — hammasi bir joyda. Real ishlaydigan mahsulot qurasiz.

DOMeventsclasslocalStorage

Bosqichlar

6 ta mavzu
  1. 01HTML strukturasi
  2. 02CSS stillari
  3. 03Class yozamiz
  4. 04DOM va eventlar
  5. 05localStorage
  6. 06Jonli demo

1. HTML strukturasi

1<!DOCTYPE html>
2<html lang="uz">
3<head>
4 <meta charset="UTF-8">
5 <title>To-do</title>
6 <link rel="stylesheet" href="style.css">
7</head>
8<body>
9 <main class="app">
10 <h1>Vazifalarim</h1>
11 <form id="form">
12 <input type="text" id="input" placeholder="Yangi vazifa..." required>
13 <button type="submit">Qo'shish</button>
14 </form>
15 <div class="filter">
16 <button data-filter="all" class="active">Hammasi</button>
17 <button data-filter="active">Faol</button>
18 <button data-filter="done">Bajarilgan</button>
19 </div>
20 <ul id="list"></ul>
21 <div id="stats"></div>
22 </main>
23 <script src="app.js"></script>
24</body>
25</html>

2. CSS stillari

1* { box-sizing: border-box; margin: 0; padding: 0; }
2body { font-family: system-ui, sans-serif; background: #0f172a; color: white; min-height: 100vh; padding: 40px 16px; }
3.app { max-width: 520px; margin: 0 auto; background: #1e293b; padding: 28px; border-radius: 16px; }
4h1 { margin-bottom: 20px; }
5
6form { display: flex; gap: 8px; margin-bottom: 16px; }
7input { flex: 1; padding: 10px 14px; border-radius: 8px; border: 1.5px solid #334155; background: #0f172a; color: white; font-size: 15px; }
8button { padding: 10px 16px; border: none; border-radius: 8px; background: #fbbf24; color: #0f172a; font-weight: 700; cursor: pointer; }
9
10.filter { display: flex; gap: 6px; margin-bottom: 16px; }
11.filter button { background: transparent; color: #94a3b8; border: 1.5px solid #334155; padding: 6px 12px; font-size: 13px; }
12.filter button.active { background: #fbbf24; color: #0f172a; border-color: #fbbf24; }
13
14ul { list-style: none; }
15li { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: #0f172a; border-radius: 8px; margin-bottom: 6px; }
16li.done span { text-decoration: line-through; color: #64748b; }
17li span { flex: 1; }
18li .del { background: transparent; color: #ef4444; font-size: 18px; padding: 0 6px; }
19#stats { margin-top: 14px; color: #64748b; font-size: 13px; text-align: center; }

3. Class yozamiz

app.js
1class Todo {
2 constructor(matn) {
3 this.id = Date.now() + Math.random();
4 this.matn = matn;
5 this.bajarildi = false;
6 }
7}
8
9class TodoApp {
10 constructor() {
11 this.vazifalar = this.yukla();
12 this.filtr = "all";
13
14 this.form = document.getElementById("form");
15 this.input = document.getElementById("input");
16 this.list = document.getElementById("list");
17 this.stats = document.getElementById("stats");
18
19 this.listenerlar();
20 this.chiz();
21 }
22
23 qoshish(matn) {
24 this.vazifalar.push(new Todo(matn));
25 this.saqla();
26 this.chiz();
27 }
28
29 ochir(id) {
30 this.vazifalar = this.vazifalar.filter(v => v.id !== id);
31 this.saqla();
32 this.chiz();
33 }
34
35 toggle(id) {
36 const v = this.vazifalar.find(v => v.id === id);
37 if (v) v.bajarildi = !v.bajarildi;
38 this.saqla();
39 this.chiz();
40 }
41}

4. DOM va eventlar

1// TodoApp ichida
2
3listenerlar() {
4 this.form.addEventListener("submit", (e) => {
5 e.preventDefault();
6 const matn = this.input.value.trim();
7 if (matn) {
8 this.qoshish(matn);
9 this.input.value = "";
10 }
11 });
12
13 document.querySelectorAll(".filter button").forEach(btn => {
14 btn.addEventListener("click", () => {
15 document.querySelector(".filter .active").classList.remove("active");
16 btn.classList.add("active");
17 this.filtr = btn.dataset.filter;
18 this.chiz();
19 });
20 });
21}
22
23chiz() {
24 const shown = this.vazifalar.filter(v => {
25 if (this.filtr === "active") return !v.bajarildi;
26 if (this.filtr === "done") return v.bajarildi;
27 return true;
28 });
29
30 this.list.innerHTML = shown.map(v => `
31 <li class="${v.bajarildi ? 'done' : ''}">
32 <input type="checkbox" ${v.bajarildi ? 'checked' : ''}
33 onchange="app.toggle(${v.id})">
34 <span>${v.matn}</span>
35 <button class="del" onclick="app.ochir(${v.id})">×</button>
36 </li>
37 `).join("");
38
39 const faol = this.vazifalar.filter(v => !v.bajarildi).length;
40 this.stats.innerText = `${faol} ta bajarilmagan, jami ${this.vazifalar.length}`;
41}

5. localStorage

1// localStorage faqat string saqlaydi — JSON.stringify/parse kerak
2
3saqla() {
4 localStorage.setItem("vazifalar", JSON.stringify(this.vazifalar));
5}
6
7yukla() {
8 const data = localStorage.getItem("vazifalar");
9 return data ? JSON.parse(data) : [];
10}
11
12// Dastur ishga tushirish
13const app = new TodoApp();

6. Jonli demo

Ishlaydigan to-do
Natijajonli

Mustaqil kengaytma

0 / 5