Skip to content

JavaScript: Procedural to OOP

John Verz edited this page May 9, 2025 · 1 revision

πŸ”Ή PART 1: Procedural To-Do App (No classes, no modules)

πŸ“„ index.html

<!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>

πŸ“„ main.js (Procedural)

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();

πŸ”Ή PART 2: Refactor to OOP with ES6 Modules

πŸ“ Folder structure

/js/
  Task.js
  TaskManager.js
  main.js
index.html

πŸ“„ index.html (Modified for module)

<!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>

πŸ“„ js/Task.js

export class Task {
  constructor(text, done = false) {
    this.text = text;
    this.done = done;
  }

  toggle() {
    this.done = !this.done;
  }
}

πŸ“„ js/TaskManager.js

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));
  }
}

πŸ“„ js/main.js

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();

πŸ” What You Learn

  • ES6 classes to encapsulate task data and behavior
  • Modules to split responsibilities (Task.js, TaskManager.js)
  • Real-world app using localStorage and DOM
Clone this wiki locally