-
Notifications
You must be signed in to change notification settings - Fork 0
JavaScript: Procedural to OOP
John Verz edited this page May 9, 2025
·
1 revision
<!DOCTYPE html>
<html>
<head>
<title>Procedural To-Do App</title>
</head>
<body>
<h1>To-Do List</h1>
<input type="text" id="taskInput" placeholder="Add task" />
<button id="addBtn">Add</button>
<ul id="taskList"></ul>
<script src="main.js"></script>
</body>
</html>
const taskInput = document.getElementById('taskInput');
const addBtn = document.getElementById('addBtn');
const taskList = document.getElementById('taskList');
let tasks = JSON.parse(localStorage.getItem('tasks')) || [];
function saveTasks() {
localStorage.setItem('tasks', JSON.stringify(tasks));
}
function renderTasks() {
taskList.innerHTML = '';
tasks.forEach((task, index) => {
const li = document.createElement('li');
li.textContent = task.text;
li.style.textDecoration = task.done ? 'line-through' : 'none';
const toggleBtn = document.createElement('button');
toggleBtn.textContent = 'Toggle';
toggleBtn.onclick = () => {
tasks[index].done = !tasks[index].done;
saveTasks();
renderTasks();
};
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.onclick = () => {
tasks.splice(index, 1);
saveTasks();
renderTasks();
};
li.append(' ', toggleBtn, deleteBtn);
taskList.appendChild(li);
});
}
addBtn.onclick = () => {
const text = taskInput.value.trim();
if (text) {
tasks.push({ text, done: false });
saveTasks();
renderTasks();
taskInput.value = '';
}
};
renderTasks();
/js/
Task.js
TaskManager.js
main.js
index.html
<!DOCTYPE html>
<html>
<head>
<title>Modular OOP To-Do App</title>
</head>
<body>
<h1>To-Do List</h1>
<input type="text" id="taskInput" placeholder="Add task" />
<button id="addBtn">Add</button>
<ul id="taskList"></ul>
<script type="module" src="js/main.js"></script>
</body>
</html>
export class Task {
constructor(text, done = false) {
this.text = text;
this.done = done;
}
toggle() {
this.done = !this.done;
}
}
import { Task } from './Task.js';
export class TaskManager {
constructor() {
this.tasks = this.load();
}
add(text) {
this.tasks.push(new Task(text));
this.save();
}
delete(index) {
this.tasks.splice(index, 1);
this.save();
}
toggle(index) {
this.tasks[index].toggle();
this.save();
}
save() {
localStorage.setItem('tasks', JSON.stringify(this.tasks));
}
load() {
const data = localStorage.getItem('tasks');
const raw = data ? JSON.parse(data) : [];
return raw.map(t => new Task(t.text, t.done));
}
}
import { TaskManager } from './TaskManager.js';
const taskInput = document.getElementById('taskInput');
const addBtn = document.getElementById('addBtn');
const taskList = document.getElementById('taskList');
const manager = new TaskManager();
function renderTasks() {
taskList.innerHTML = '';
manager.tasks.forEach((task, index) => {
const li = document.createElement('li');
li.textContent = task.text;
li.style.textDecoration = task.done ? 'line-through' : 'none';
const toggleBtn = document.createElement('button');
toggleBtn.textContent = 'Toggle';
toggleBtn.onclick = () => {
manager.toggle(index);
renderTasks();
};
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.onclick = () => {
manager.delete(index);
renderTasks();
};
li.append(' ', toggleBtn, deleteBtn);
taskList.appendChild(li);
});
}
addBtn.onclick = () => {
const text = taskInput.value.trim();
if (text) {
manager.add(text);
taskInput.value = '';
renderTasks();
}
};
renderTasks();
- ES6 classes to encapsulate task data and behavior
-
Modules to split responsibilities (
Task.js
,TaskManager.js
) - Real-world app using localStorage and DOM