|
1 | | -const form = document.getElementById('form'); const input = document.getElementById('input'); const list = document.getElementById('list'); |
| 1 | +const form = document.getElementById('form'); |
| 2 | +const input = document.getElementById('input'); |
| 3 | +const list = document.getElementById('list'); |
| 4 | + |
2 | 5 | let items = []; |
3 | | -form.addEventListener('submit', e => { e.preventDefault(); items.push({ id: crypto.randomUUID(), text: input.value, done: false }); input.value = ''; render(); }); |
4 | | -function render() { list.innerHTML = ''; for (const it of items) { const li = document.createElement('li'); li.innerHTML = `<label><input type="checkbox" ${it.done ? 'checked' : ''}> ${it.text}</label> <button class="del">×</button>`; li.querySelector('input').addEventListener('change', e => { it.done = e.target.checked; }); li.querySelector('.del').addEventListener('click', () => { items = items.filter(x => x.id !== it.id); render(); }); list.appendChild(li); } } |
| 6 | + |
| 7 | +function escapeHTML(text) { |
| 8 | + const div = document.createElement('div'); |
| 9 | + div.textContent = text; |
| 10 | + return div.innerHTML; |
| 11 | +} |
| 12 | + |
| 13 | +form.addEventListener('submit', (e) => { |
| 14 | + e.preventDefault(); |
| 15 | + items.push({ id: crypto.randomUUID(), text: input.value.trim(), done: false }); |
| 16 | + input.value = ''; |
| 17 | + render(); |
| 18 | +}); |
| 19 | + |
| 20 | +function render() { |
| 21 | + list.innerHTML = ''; |
| 22 | + for (const it of items) { |
| 23 | + const li = document.createElement('li'); |
| 24 | + if (it.done) li.classList.add('done'); |
| 25 | + |
| 26 | + li.innerHTML = ` |
| 27 | + <label> |
| 28 | + <input type="checkbox" ${it.done ? 'checked' : ''}> |
| 29 | + <span>${escapeHTML(it.text)}</span> |
| 30 | + </label> |
| 31 | + <button class="del" aria-label="Delete">×</button> |
| 32 | + `; |
| 33 | + |
| 34 | + const checkbox = li.querySelector('input'); |
| 35 | + checkbox.addEventListener('change', (e) => { |
| 36 | + it.done = e.target.checked; |
| 37 | + li.classList.toggle('done', it.done); |
| 38 | + }); |
| 39 | + |
| 40 | + li.querySelector('.del').addEventListener('click', () => { |
| 41 | + items = items.filter((x) => x.id !== it.id); |
| 42 | + render(); |
| 43 | + }); |
| 44 | + |
| 45 | + list.appendChild(li); |
| 46 | + } |
| 47 | +} |
| 48 | + |
5 | 49 | render(); |
6 | 50 | // TODOs: save to localStorage; add filter (all/active/done); sort; theme switcher |
0 commit comments