Search code examples
javascripthtmlcss

How to apply CSS dynamically with JavaScript for the ToDo list?


I'm practicing in creating a basic To-Do web app and I can't figure out how to make it so that after I click on “submit” it creates another task instead of replacing the existing one, I've tried to dynamically create another list, but it overlaps the existing one even if I position it absolutely, and I want it to look the same, to replicate the exact same CSS styling but with whatever I type on the input boxes, may you help me? Here's an example of how I was trying to make it look: Example

Here's the code

//Dark mode background colors
document.addEventListener("DOMContentLoaded", function () {
  const darkModeToggle = document.getElementById("darkmode-toggle");
  const body = document.body;

  darkModeToggle.addEventListener("change", function () {
    if (this.checked) {
      body.classList.add("dark-mode");
    } else {
      body.classList.remove("dark-mode");
    }
  });
});

//Window pop up when clicking new button
document.addEventListener("DOMContentLoaded", function () {
  const newButton = document.getElementById("new-btn");
  const wholeContainer = document.querySelector(".whole-container");
  const submitButton = document.querySelector(".submit-btn");
  const taskNameInput = document.getElementById("taskName");
  const taskDayInput = document.getElementById("taskDay");
  const taskDateInput = document.getElementById("taskDate");
  const taskNameSpan = document.getElementById("task-name");
  const taskDaySpan = document.getElementById("task-day");
  const taskDateSpan = document.getElementById("task-date");
  const checkboxInput = document.getElementById("check-mark");

  function showWholeContainer() {
    wholeContainer.style.visibility = "visible";
    wholeContainer.style.opacity = "1";
    newButton.disabled = true;

    // Add event listener to close the window when clicking outside of it
    document.addEventListener("click", clickOutsideHandler);
  }

  function hideWholeContainer() {
    wholeContainer.style.opacity = "0";
    setTimeout(() => {
      wholeContainer.style.visibility = "hidden";
      newButton.disabled = false;
    }, 200);

    // Remove the event listener to prevent unnecessary checks
    document.removeEventListener("click", clickOutsideHandler);
  }

  function clickOutsideHandler(event) {
    if (!wholeContainer.contains(event.target) && event.target !== newButton) {
      hideWholeContainer();
    }
  }

  function resetForm() {
    taskNameInput.value = ""; // Clear task name input
    taskDayInput.value = ""; // Clear task date input
    taskDateInput.value = ""; // Clear task date input
  }

  function showTaskList() {
    const wholeContainerTwo = document.querySelector(".whole-container-two");
    wholeContainerTwo.style.visibility = "visible";
    wholeContainerTwo.style.opacity = "1";
  }

  function validateForm() {
    if (
      taskNameInput.value.trim() === "" ||
      taskDayInput.value.trim() === "" ||
      taskDateInput.value.trim() === ""
    ) {
      alert("Please fill out task name, day, and task date fields.");
      return false;
    }
    return true; // Return true if form is valid
  }

  newButton.addEventListener("click", function () {
    showWholeContainer();
  });

  checkboxInput.addEventListener("change", function () {
    if (this.checked) {
      taskNameSpan.classList.add("checked");
    } else {
      taskNameSpan.classList.remove("checked");
    }
  });

  submitButton.addEventListener("click", function (event) {
    event.preventDefault();
    if (validateForm()) {
      taskNameSpan.textContent = taskNameInput.value;
      taskDaySpan.textContent = taskDayInput.value;
      taskDateSpan.textContent = taskDateInput.value;
      resetForm();
      showTaskList();
      hideWholeContainer();
    }
  });

  hideWholeContainer(); // Initially hide the container
});
header {
  position: fixed;
}

body {
  margin: 0;
  padding: 0;
  font-family: "Roboto", sans-serif;
  background-color: #f1ebdd;
  overflow-x: hidden;
}

/*header*/

.nav-container {
  position: absolute;
  display: flex;
  flex-direction: column;
  flex: space-between;
  align-items: flex-start;
  z-index: 2;
}

.nav-container button {
  font-family: "Roboto", sans-serif;
  font-weight: 500;
  font-style: normal;
  font-size: 20px;
  border-radius: 25px;
  border-color: transparent;
  background-color: #58585a;
  color: #f1ebdd;
  cursor: pointer;
}

.nav-container button:hover {
  background-color: #f1ebdd;
  color: #58585a;
  transition: 0.6ms;
}

.user-btn {
  margin: 45px 0px 0px 50px;
  padding: 25px 80px 25px 80px;
}

.mylist-btn {
  margin: 45px 0px 0px 50px;
  padding: 10% 25% 10% 26%;
}

.categories-btn {
  margin: 45px 0px 0px 50px;
  padding: 10% 20% 10% 21%;
}

.calendar-btn {
  margin: 45px 0px 0px 50px;
  padding: 10% 23% 10% 25%;
}

.settings-btn {
  margin: 45px 0px 0px 50px;
  padding: 10% 23% 10% 26%;
}

.about-btn {
  margin: 45px 0px 0px 50px;
  padding: 10% 23% 10% 23%;
}

/*Day/night Switch*/

.label-data {
  display: block;
  position: absolute;
  cursor: pointer;
  margin: 775px 0% 0% 50px;
  width: 200px;
  height: 80px;
  border-radius: 200px;
  background-color: #f1ebdd;
  box-shadow: inset 0px 0px 10px 2px rgba(0, 0, 0, 0.2);
  z-index: 2;
}

.label-data:after {
  position: absolute;
  content: "";
  width: 80px;
  height: 80px;
  top: 0px;
  left: 0px;
  border-radius: 180px;
  background: linear-gradient(180deg, rgb(255, 170, 58), #d8a80b);
}

.input-data {
  visibility: hidden;
  width: 0;
  height: 0;
}

.input-data:checked + .label-data {
  background: #242424;
}

.input-data:checked + .label-data:after {
  left: 200px;
  transform: translateX(-100%);
  background: linear-gradient(180deg, #a3a3a3, #353535);
}

.label-data,
.label-data:after {
  transition: 0.4s;
}

.label-data:active:after {
  width: 50px;
}

.label-data svg {
  position: absolute;
  width: 70px;
  top: 5px;
  z-index: 100;
}

.label-data svg.sun {
  left: 5px;
  fill: #f1ebdd;
  border-radius: 50px;
  transition: 0.4s;
}

.label-data svg.moon {
  left: 125px;
  fill: #333333;
  transition: 0.4s;
}

.input-data:checked + .label-data svg.sun {
  fill: #242424;
}

.input-data:checked + .label-data svg.moon {
  fill: #f1ebdd;
}

.input-data:checked + .label-data + .background {
  background: #242424;
}

/*sidebar fixed background color*/

.sidebar-background h1 {
  position: fixed;
  padding: 40% 7% 10% 10%;
  margin: -1% 90% 0% 0%;
  background-color: #dbd8d3;
  z-index: 1;
}

/*to-do list app*/

.todo-container {
  position: absolute;
  margin: 70px 0px 0px 90%;
  z-index: 100;
}

.todo-container .new {
  padding: 3px 18px 3px 18px;
  font-family: "Roboto", sans-serif;
  font-weight: 500;
  font-style: normal;
  font-size: 20px;
  border-radius: 25px;
  color: #f1ebdd;
  background-color: #4eaabe;
  border-color: transparent;
  text-decoration: none;
  cursor: pointer;
  transition: 0.8s;
}

.todo-container .new:hover {
  padding: 5px 25px 5px 25px;
  transition: 0.8s;
}

/*to-do list app window pop up*/

.whole-container {
  display: hidden;
  opacity: 0;
  transition: visibility 0.8s ease, opacity 0.2s ease;
}

.hidden {
  /*JavaScript code*/
  display: none;
}

.window-wrapper {
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
  padding: 150px 150px;
  border-radius: 25px;
  background-color: #dbd8d3;
  transition: 0.4s;
  z-index: 1000;
}

.window-wrapper .form-data {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: left;
  gap: 25px;
  width: 150%;
  font-family: "Roboto", sans-serif;
  font-weight: 500;
  font-style: normal;
  border-radius: 25px;
}

.form-data label {
  font-family: "Roboto", sans-serif;
  font-weight: 500;
  font-style: normal;
  font-size: 20px;
  text-align: center;
  color: #f1ebdd;
  border-radius: 25px;
  padding: 10px;
  background-color: #58585a;
}

.form-data input {
  border-color: transparent;
  border-radius: 25px;
  font-size: 20px;
  padding: 10px;
  color: #58585a;
  background-color: #f1ebdd;
  outline-color: #58585a;
}

.form-data .submit-btn {
  font-family: "Roboto", sans-serif;
  font-weight: 500;
  font-style: normal;
  font-size: 20px;
  border-radius: 25px;
  border-color: transparent;
  background-color: #58585a;
  color: #f1ebdd;
  cursor: pointer;
}

/*to-do list after window*/

.whole-container-two {
  opacity: 0;
  visibility: hidden;
  transition: visibility 0.8s ease, opacity 0.2s ease;
}

.task-wrapper {
  position: absolute;
  margin: 177px 0% 0% 20%;
  padding: 0% 1% 0% 0%;
  border-radius: 25px;
  background-color: #4eaabe;
  z-index: -50;
}

.task-wrapper ul {
  list-style-type: none;
}

.task-list li {
  margin: 0px 0px 0px 30px;
}

.todo-item span {
  text-align: left;
  font-family: "Roboto", sans-serif;
  font-weight: 500;
  font-style: normal;
  font-size: 20px;
}

.checkbox-input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.checkmark-label {
  position: absolute;
  cursor: pointer;
}

.fa-circle-check {
  margin: -8px 0px 0px -60px;
  font-size: 40px;
  color: #f1ebdd;
  background-color: #f1ebdd;
  border-radius: 25px;
}

.checkbox-input:checked + .checkmark-label .fa-circle-check {
  color: #ace464;
  background-color: transparent;
  transition: 0.2s;
}

.todo-item .task-date-list {
  position: absolute;
  margin: -60px 0% 0% -70px;
  padding: 5px 1% 5px 1%;
  font-size: 20px;
  color: #bcb7af;
  z-index: -50;
}

.task-name-list {
  color: #f1ebdd;
}

.task-name-list.checked {
  text-decoration-line: line-through;
}

.todo-item .task-day-list {
  position: absolute;
  margin: -100px 0% 0% -75px;
  padding: 5px 1% 5px 1%;
  font-size: 25px;
  color: #58585a;
  z-index: -50;
}

/* Dark mode background colors */
.dark-mode {
  background-color: #242424;
  transition: 0.4s;
}

.dark-mode .nav-container button {
  background-color: #242424;
  color: #f1ebdd;
}

.dark-mode .nav-container button:hover {
  background-color: #f1ebdd;
  color: #242424;
  transition: 0.6ms;
}

.dark-mode .input-data:checked + .label-data {
  background: #242424;
}

.dark-mode .input-data:checked + .label-data:after {
  background: linear-gradient(180deg, #6e46fd, #2f0ea5);
}

.dark-mode .input-data:checked + .label-data svg.sun {
  fill: #242424;
}

.dark-mode .input-data:checked + .label-data svg.moon {
  fill: #f1ebdd;
}

.dark-mode .sidebar-background h1 {
  background: linear-gradient(180deg, #6e46fd, #2f0ea5);
  transition: 0.4s;
}

.dark-mode .window-wrapper {
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
  padding: 150px 150px;
  border-radius: 25px;
  background: linear-gradient(180deg, #6e46fd, #2f0ea5);
  transition: 0.4s;
  z-index: 300;
}

.dark-mode .form-data label {
  font-family: "Roboto", sans-serif;
  font-weight: 500;
  font-style: normal;
  font-size: 20px;
  text-align: center;
  color: #f1ebdd;
  border-radius: 25px;
  padding: 10px;
  background-color: #242424;
}

.dark-mode .form-data input {
  border-color: transparent;
  border-radius: 25px;
  font-size: 20px;
  padding: 10px;
  color: #242424;
  background-color: #f1ebdd;
  outline-color: #242424;
}

.dark-mode .form-data .submit-btn {
  font-family: "Roboto", sans-serif;
  font-weight: 500;
  font-style: normal;
  font-size: 20px;
  border-radius: 25px;
  border-color: transparent;
  background-color: #242424;
  color: #f1ebdd;
  cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>MyList: Enhanced to-do list app</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="script.js"></script>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"
      rel="stylesheet"
    />
    <script
      src="https://kit.fontawesome.com/3ba961a955.js"
      crossorigin="anonymous"
    ></script>
  </head>
  <body>
    <header>
      <!--Sidebar navigation-->
      <nav class="nav-container" role="button">
        <button type="button" class="user-btn">User</button>
        <button type="button" class="mylist-btn">My lists</button>
        <button type="button" class="categories-btn">Categories</button>
        <button type="button" class="calendar-btn">Calendar</button>
        <button type="button" class="settings-btn">Settings</button>
        <button type="button" class="about-btn">About us</button>
      </nav>
      <!--Day/night Switch-->
      <input class="input-data" type="checkbox" id="darkmode-toggle" />
      <label class="label-data" for="darkmode-toggle">
        <svg
          version="1.1"
          class="sun"
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
          <g
            id="SVGRepo_tracerCarrier"
            stroke-linecap="round"
            stroke-linejoin="round"
          ></g>
          <g id="SVGRepo_iconCarrier">
            <path
              d="M12 3V4M12 20V21M4 12H3M6.31412 6.31412L5.5 5.5M17.6859 6.31412L18.5 5.5M6.31412 17.69L5.5 18.5001M17.6859 17.69L18.5 18.5001M21 12H20M16 12C16 14.2091 14.2091 16 12 16C9.79086 16 8 14.2091 8 12C8 9.79086 9.79086 8 12 8C14.2091 8 16 9.79086 16 12Z"
              stroke="#f1ebdd"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
            ></path>
          </g>
        </svg>
        <svg
          version="1.1"
          class="moon"
          viewBox="0 0 24 24"
          fill="none"
          xmlns="http://www.w3.org/2000/svg"
        >
          <g id="SVGRepo_bgCarrier1" stroke-width="0"></g>
          <g
            id="SVGRepo_tracerCarrier2"
            stroke-linecap="round"
            stroke-linejoin="round"
          ></g>
          <g id="SVGRepo_iconCarrier3">
            <path
              d="M3.32031 11.6835C3.32031 16.6541 7.34975 20.6835 12.3203 20.6835C16.1075 20.6835 19.3483 18.3443 20.6768 15.032C19.6402 15.4486 18.5059 15.6834 17.3203 15.6834C12.3497 15.6834 8.32031 11.654 8.32031 6.68342C8.32031 5.50338 8.55165 4.36259 8.96453 3.32996C5.65605 4.66028 3.32031 7.89912 3.32031 11.6835Z"
              stroke="#f1f1f1f1"
              stroke-width="0"
              stroke-linecap="round"
              stroke-linejoin="round"
            ></path>
          </g>
        </svg>
      </label>
      <!--sidebar fixed background color-->
      <div class="sidebar-background">
        <h1></h1>
      </div>
    </header>
    <!--to-do list app-->
    <div class="todo-container">
      <button type="button" class="new" id="new-btn">New</button>
    </div>
    <!--to-do list app window pop up-->
    <div class="whole-container">
      <div class="window-wrapper">
        <form class="form-data">
          <label for="taskName">Task Name</label>
          <input
            type="text"
            id="taskName"
            name="taskName"
            placeholder="What's in your mind?"
          />
          <label for="taskDate">Task Date and Day</label>
          <input
            type="text"
            id="taskDate"
            name="taskDate"
            placeholder="Set a date for your task"
          />
          <input
            type="text"
            id="taskDay"
            name="taskDay"
            placeholder="Set a day for your task"
          />
          <button type="submit" class="submit-btn">Submit</button>
        </form>
      </div>
    </div>
    <!--to-do list after window-->
    <div class="whole-container-two">
      <div class="task-wrapper">
        <ul class="task-list">
          <li class="todo-item">
            <input type="checkbox" id="check-mark" class="checkbox-input" />
            <label for="check-mark" class="checkmark-label"
              ><i class="fa-solid fa-circle-check"></i
            ></label>
            <span class="task-day-list" id="task-day">Task Day</span>
            <span class="task-date-list" id="task-date">Task Date</span>
            <span class="task-name-list" id="task-name">Task Name</span>
          </li>
        </ul>
      </div>
    </div>
  </body>
</html>


Solution

  • You are never really adding a new element to the task list. You are simply changing the values of the one task that is already there. Think about create an array of tasks and every time you add a new task you append it to that array. Out of this array you can create your task list dynamically. This simple example will hopefully help you figure it out:

    let tasks = [];
    let form = document.querySelector('form');
    let list = document.querySelector('.list');
    
    form.addEventListener('submit', (e) => {
      e.preventDefault();
      let task_text = form.querySelector('#task_text').value;
      let task_date = form.querySelector('#task_date').value;
      tasks.push({
        text: task_text,
        date: task_date
      });
      form.reset();
      updateList();
    });
    
    function updateList() {
      list.innerHTML = '';
      tasks.forEach((task) => {
        let taskitem = document.createElement('li');
        taskitem.textContent = task.text + ' (' + task.date + ')';
        list.append(taskitem);
      });
    }
    <ul class="list"></ul>
    
    <form>
      <input type="text" id="task_text" placeholder="What's in your mind?">
      <input type="text" id="task_date" placeholder="Task date">
      <button>Add Task</button>
    </form>