to-do list

to-do list with progress circle

by tailslider13

HTML

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

    <!-- Required meta tags -->
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous" />

  </head>

  <div class="container">

    <body id="body">

      <header class="row justify-content-end">

        <h1 class="col-4">Take note</h1>

        <!-- Progress ring  -->
        <div class="col-4">
          <div class="chart" id="graph"></div>
        </div>

      </header>

      <!-- Input field and button -->
      <div class="row inputContainer rounded">
        <input class="col-auto" type="newTask" placeholder="Enter new Task" id="addTask" />
        <button class="col-auto" id="btnAdd">Add</button>
      </div>

      <!-- List of tasks created  -->
      <div class="listContainer">
        <ul class="taskList rounded" id="taskList"></ul>
      </div>

      <footer class="row" id="footer">
        <h6 class="col w-100">2021</h6>
      </footer>

      <!-- BOOTSTRAP -->
      <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous">
      </script>
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.min.js" integrity="sha384-lpyLfhYuitXl2zRZ5Bn2fqnhNAKOAaM/0Kr9laMspuaMiZfGmfwRNFh8HlMy49eQ" crossorigin="anonymous">
      </script>

    </body>

  </div>

</html>

CSS

#body {
  background-color: #046582;
}

header {
  background-color: #f39189;
  padding: 50px;
  margin: 50px;
  position: sticky;
  top: 0px;
}

h1 {
  text-align: center;
}

.listItem {
  margin: 20px 0px;
  background-color: white;
}

.container {
  background-color: #c4c4c4;
}

.taskList {
  list-style-type: none;
  background-color: transparent;
  overflow: hidden;
  margin-top: 150px;
}

.inputContainer {
  margin: 50px;
  padding: 20px;
  max-width: 50%;
  width: 100%;
  background-color: #f39189;
}

#footer {
  text-align: center;
  position: sticky;
  bottom: 0px;
  background-color: #f39189;
  padding: 20px;
}

.deleteButton {
  background-image: url("/content/delete.png");
  background-repeat: no-repeat;
  background-size: cover;
  cursor: pointer;
  width: 30px;
  height: 30px;
  margin: 15px;
}

#addTask {
  font-family: Verdana, Geneva, Tahoma, sans-serif;
  font-size: 1.3rem;
}

.taskName {
  font-family: Verdana, Geneva, Tahoma, sans-serif;
  font-size: 1.2rem;
}

.listContainer {
  height: 1080px;
}

.inputContainer {
  position: fixed;
}

.checkedbox {
  text-decoration: line-through;
  color: #f39189;
}

/* START Styling Progress ring */

.chart {
  position: relative;
  /* margin:0px; */
  width: 220px;
  height: 220px;
}

canvas {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
}

span {
  color: #046582;
  display: block;
  line-height: 220px;
  text-align: center;
  width: 220px;
  font-family: sans-serif;
  font-size: 30px;
  font-weight: 100;
  margin-left: 5px;
}

/* Links progress ring */
/* https://stackoverflow.com/questions/14222138/css-progress-circle
http://jsfiddle.net/Aapn8/3410/ */

/* END Styling Progress ring */

JavaScript

const inputField = document.getElementById("addTask");
const taskList = document.getElementById("taskList");

const inputFocus = () => {
  const input = document.getElementById("addTask");
  input.focus();
};
inputFocus();

inputField.addEventListener("keyup", (event) => {
  if (event.key === "Enter") {
    addTask();
  }
});

function addTask() {
  const userInputTask = inputField.value;

  // Validate for empty input
  if (
    userInputTask === "" ||
    userInputTask.split(" ").join("") === ""
  ) {
    alert("Please enter a valid task.");
    return false;
  }
  checkedItemFn();

  // Create the id for the new task
  newDate = new Date();
  newTime = newDate.getTime();
  newTaskId = newTime;

  newListTemplate = `<li class="listItem" id="${newTaskId}" data-task-id=${newTaskId}>
                          <div class="row align-items-center">
                                <div class="col-auto m-3" ><input type="checkbox" class="box"></div>
                                <div class="col taskName">${userInputTask}</div>
                                <div class="col-auto"><input type="button" value="" class="btn deleteButton" data-delete></div>
                           </div>
                        </li>`;

  taskList.insertAdjacentHTML("afterbegin", newListTemplate);

  pendingTasks++;

  const deleteButtons = document.querySelectorAll("[data-delete]");

  for (let button of deleteButtons) {
    button.addEventListener("click", deleteTask);
  }
  checkedItemFn();
  inputField.value = "";
}

function checkedItemFn() {
  const checkedboxes = document.querySelectorAll(".box");

  checkedboxes.forEach((box) => {
    box.addEventListener("click", function(event) {
      event.target.parentElement
        .closest("li")
        .children[0].children[1].classList.toggle("checkedbox");
      const moveItem = event.target.parentElement.closest("li");
      document.querySelector("ul").append(moveItem);
      completedTasks++;
    });
  });
}

const btnAdd =...