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 mavzu1. 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 ichida2
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 kerak2
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 tushirish13const app = new TodoApp();6. Jonli demo
Ishlaydigan to-do
Natijajonli