Back

Technologies:

javascriptjavascript
avatar
Tolerim
8 hours ago

How can I create a ToDo list using classes?

Hey everyone, I'm currently grappling with creating a to-do list using classes in JavaScript. Since this is my first time working with object-oriented programming, I don't know how to piece together all the necessary components to achieve my desired outcome. I'm having trouble figuring out how to add input to the toDo array and then display it within the ul element. To give a brief overview of my code, it's comprised of two classes:

  1. List, where tasks can be added or removed from the array, and
  2. Render, where added or removed tasks are displayed.
Any assistance with this would be greatly appreciated!

class List {
  #toDo = [];
  constructor(render) {
    this.render = render;
    this.render.renderList(this.toDo);
  }

  addTask(task) {
    this.toDo.push(task);
    this.render.renderList(this.toDo);
  }

  removeTask(task) {
    this.toDo.filter((item) => item != task);
  }
}

class Render {
  constructor(input) {
    this.input = input;
    this.task = this.input.querySelector("input");
    this.btn = this.input.querySelector("button");
    this.ul = this.input.querySelector(".tasks");
  }
  onRemoveTaskCallBack = () => {};
  renderList(toDo) {
    this.ul.innerHTML = "";
    toDo.forEach((task) => {
      const li = document.createElement("li");
      li.innerHTML = `${task} <button>Delete</button>`;
      this.ul.appendChild(li);
      this.btn.addEventListener("click", () => {
        this.render.addTask(this.task.value);
        this.task.value = "";
      });
    });
  }
}

const render = new Render(document.querySelector("#to-do-container"));
const list = new List(render);
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        margin: 80px auto;
        text-align: center;
      }
      input {
        width: 20%;
      }
    </style>
  </head>
  <body>
    <div id="to-do-container">
      <input type="text" />
      <button>Add Task</button>
      <ul class="tasks"></ul>
    </div>

    <script src="List.js"></script>
    <script src="Render.js"></script>
  </body>
</html>

Answers(1)
avatar
Tolerim
8 hours ago
Verified Answer
In your List class, the addTask method should simply push the passed list argument to the this.toDo array. To render the updated list, you can simply call the renderList method of this.render and pass in this.toDo. So the corrected List class should look like this:
class List {
  #toDo = [];
  constructor(render) {
    this.render = render;
    this.render.renderList(this.toDo);
  }

  addTask(list) {
    this.toDo.push(list);
    this.render.renderList(this.toDo);
  }

  removeTask(list) {
    this.toDo = this.toDo.filter((word) => word !== list);
    this.render.renderList(this.toDo);
  }
}
In your Render class, you should listen to the click event of the "Add Task" button and call the addTask method of your List instance to add the task to the array. Also, you can use the insertAdjacentHTML method of the ul element to add the new task to the DOM. So the corrected Render class should look like this:
class Render {
  constructor(input) {
    this.input = input;
    const task = this.input.querySelector("input");
    const btn = this.input.querySelector("button");
    const ul = this.input.querySelector(".tasks");
    btn.addEventListener("click", () => {
      list.addTask(task.value);
      ul.insertAdjacentHTML("beforeend", `<li>${task.value}<button>Delete</button></li>`);
      task.value = "";
    });
  }

  onRemoveTaskCallBack = () => {};

  renderList(toDo) {
    const ul = this.input.querySelector(".tasks");
    ul.innerHTML = "";
    toDo.forEach((task) => {
      ul.insertAdjacentHTML("beforeend", `<li>${task}<button>Delete</button></li>`);
    });
  }
}
With these corrections, you should be able to add and remove tasks from your todo list successfully.
;