Displaying the number of tasks completed compared to the total number of tasks within a JavaScript ToDo list

Currently, I'm in the process of creating a basic ToDo list using HTML, JS, and CSS. The last task on my list is to display to the user the total number of tasks and how many have been completed. For instance, if there are 3 completed tasks out of 7 in total, it should show as 3/7. I've attempted to achieve this using event listeners but have been unable to make it work. How can I utilize the output element in both the HTML and JS to accomplish this?

var button = document.getElementById('button')
var ul = document.getElementById('todo')
var output = document.getElementsByName('result')


button.addEventListener("click", addTask);
button.addEventListener("click", function(event) {
  event.preventDefault()
})

function addTask() {
  var checkbox = document.createElement("INPUT")
  checkbox.setAttribute("type", "checkbox");
  var label = document.createElement("LABEL");
  var li = document.createElement("LI");
  var task = document.createTextNode(document.getElementById('task').value);
  label.appendChild(task)
  li.appendChild(label)
  li.insertBefore(checkbox, li.childNodes[0])
  ul.appendChild(li)

  var date = new Date()
  tasks.push({
    text: document.getElementById('task').value,
    date: date
  })
}

var tasks = []
console.log(tasks)
#todo {
  list-style-type: none;
  margin-left: 0;
  padding-left: 0;
}

input[type=checkbox]:checked + label {
  text-decoration: line-through;
}
<!doctype html>
<html>

<head>
  <link rel="stylesheet" href="style.css">
  <meta charset="utf-8">
</head>

<body>

  <header>
    <h1>To-do list</h1>
  </header>

  <form class="" action="" method="">
    <input type="submit" name="button" value="Add task" id="button">
    <input type="text" name="input" id="task" autofocus>
    <output name="result"></output>
    <ul id="todo"></ul>
  </form>

  <script type="text/javascript" src="todo.js"></script>

</body>

</html>

Answer №1

This method includes two additional elements to display completed tasks and the total count. It also attaches the change event to each new checkbox created to detect when the user interacts with them.

var button = document.getElementById('button')
var ul = document.getElementById('todo')
var output = document.getElementsByName('result')
var total = document.getElementById('total')
var completed = document.getElementById('completed')

button.addEventListener("click", addTask);
button.addEventListener("click", function(event) {
  event.preventDefault();
});

function addTask() {
  var checkbox = document.createElement("INPUT");
  checkbox.setAttribute("type", "checkbox");
  
  // Increase the total count by one.
  total.textContent = +total.textContent + 1;
  
  //Trigger the completed event
  checkbox.addEventListener("change", function(event) {
    if (this.checked) completed.textContent = +completed.textContent + 1;
    else completed.textContent = +completed.textContent - 1;
  });
  
  var label = document.createElement("LABEL");
  var li = document.createElement("LI");
  var task = document.createTextNode(document.getElementById('task').value);
  label.appendChild(task)
  li.appendChild(label)
  li.insertBefore(checkbox, li.childNodes[0])
  ul.appendChild(li)

  var date = new Date()
  tasks.push({
    text: document.getElementById('task').value,
    date: date
  });
}

var tasks = []
console.log(tasks)
#todo {
  list-style-type: none;
  margin-left: 0;
  padding-left: 0;
}

input[type=checkbox]:checked+label {
  text-decoration: line-through;
}
<!doctype html>
<html>

<head>
  <link rel="stylesheet" href="style.css">
  <meta charset="utf-8">
</head>

<body>

  <header>
    <h1>To-do list</h1>
  </header>

  <form class="" action="" method="">
    <input type="submit" name="button" value="Add task" id="button">
    <input type="text" name="input" id="task" autofocus>
    <output name="result"></output>
    <p>My completed todos: <span id='completed'>0</span> / <span id='total'>0</span> </p>
    <ul id="todo"></ul>
  </form>

  <script type="text/javascript" src="todo.js"></script>

</body>

</html>

Answer №2

The issue you're encountering is due to placing the code inside a form element. Forms should only be used when submitting POST or PUT requests to the server. When the submit button is clicked, the browser refreshes the page as it sends a POST request to the server which may result in a 404 - Not Found error. First step, remove the form element.

Additionally, I recommend using jQuery instead of traditional DOM manipulation methods for better performance and readability. I made some adjustments to your code in this Plunker for it to work correctly. You can check it out here.

var tasks = []

var button = $('#button')
var ul = $('#todo')
var output = $('#result')

button.click(function() {
  addTask();
});

function addTask() {
  var li = $('<li/>');

  var checkbox = $('<input/>')
    .attr('type', 'checkbox');

  var taskText = $('#task').val();
  var label = $('<label/>')
    .html(taskText);

  li.append(checkbox);
  li.append(label);

  ul.append(li);

  var now = new Date()
  tasks.push({
    text: taskText,
    date: now
  });
  console.log(tasks);

}

<!doctype html>
<html>

<head>
  <link rel="stylesheet" href="style.css">
  <meta charset="utf-8">
</head>

<body>

  <header>
    <h1>To-do list</h1>
  </header>

  <div>
    <button name="button" value="Add task" id="button">Add task</button>
    <input type="text" name="input" id="task" autofocus>
    <output name="result"></output>
    <ul id="todo"></ul>
  </div>

  <script
    src="https://code.jquery.com/jquery-3.3.1.min.js"
    integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
    crossorigin="anonymous"></script>
  <script type="text/javascript" src="todo.js"></script>

</body>

</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Total number of goals scored by a single team (extracted from JSON data)

My data consists of football games in a JSON file [ { "game_id":"258716", "game_date_start":"2016-08-15", "season": "2016", "team_1_id":"119", "team_2_id":"120", "team_1_goals_quantity":"2", "team_2_goals ...

Empty text box

I've been attempting to clear ng-model inputs, but haven't had any success and I can't seem to figure out why. Here is what I have: <button ng-click="$ctrl.clear()"></button> And in the clear action, I have: $scope.$event = n ...

The error "navigator.permissions.query is not a defined object" is encountered in the evaluation

Whenever I try to access my website on an iPhone 7, I encounter a frustrating error. The main screen loads without any issues, but as soon as I click on something, a white bank screen appears. I believe this piece of code might be the cause: useEffect( ...

How can the color of unselected mat-steps be customized in Angular?

In my CSS code, I have specified the styling for the selected mat-step as follows: ::ng-deep .mat-step-header .mat-step-icon-selected { background-color: #a94442; } While this code works well, I encountered a need to update only certain blue icons: ...

Unique ActionBar design for my NativeScript-Vue application

I'm currently working on customizing the ActionBar for my nativescript-vue app. I have implemented FlexBoxLayout within the ActionBar, but I am facing an issue where the icon and title of the bar are not aligning to the left as intended; instead, they ...

Error: The function `map` cannot be applied to `cardsData`

I'm encountering an issue where I need to store user queries in cardsData and then map through the data within cardsData. However, when I run the code on my terminal, it throws an error. As a beginner, I've researched various forums that mention ...

Scrolling horizontally within SVG graphics

Check out this JSFiddle body { background-color: #111111; color: #ffffff; /*max-width: 100%;*/ overflow-x: hidden; } .row { max-width: 100rem; } .svgrow { min-width: 70rem; } .svgrow svg { overflow-x: auto; } I am trying to ma ...

Different browsers have varying ways of handling transition end callbacks with AddEventListener()

Each browser has its own transition end callback. Therefore, I find myself needing to use addEventListener() for each one. addEventListener('transitionend', function() { // code here }); addEventListener('webkitTransitionEnd', funct ...

Unable to display background image on Webpage due to blank page issue while uploading it with HTML and CSS

I've been attempting to build a webpage with an image as the background, but I seem to be facing some issues. Instead of seeing the desired image, all I get is a blank white page. The folder named "images" is located in the same directory as my HTML a ...

How can you include a key event handler that specifically looks out for the Space key being pressed?

When a user presses the Enter key (and button is in focus), the button opens. However, I would like to also open the link button when the user presses the space bar. Buttons should be activated using the Space key, while links should be activated with the ...

A guide to implementing lazy loading using BXSlider

I have implemented an image gallery using Bxslider, but I am facing an issue with the loading time as there are more than 15 images in each slide. To address this problem, I want to load images one by one when a particular slide appears. I came across an e ...

The "html" element fails to achieve a full height when applying a 100% height setting

I am facing a height problem of 100% <!doctype html> <html> <head> <meta charset="utf-8"> <title>My Dreamweaver Website</title> <link rel="stylesheet" href="style.css"> </head> <body> <section clas ...

Create an array populated with unclosed HTML tags that need to be rendered

I'm trying to display a simple list, but it seems like React is having trouble rendering unclosed HTML elements that are pushed onto the list. This results in an error: ReferenceError: el is not defined If I use single quotes (') bookingStat ...

Analyzing the value of a tab with Protractor测试

Below is my HTML code showcasing a list of tabs: <mat-tab-group> <mat-tab label="A"> <app-A></app-A> </mat-tab> <mat-tab label="B"> <app-B></app-B> </mat ...

jQuery Plugin - iDisplayLength Feature

I am currently using DataTables version 1.10.10 and I am looking to customize the main plugin Javascript in order to change the iDisplayLength value to -1. This adjustment will result in displaying "All" by default on all data tables, allowing users to fil ...

The thumb of the range input is misaligned with the axis markers

The handle, also known as the knob in this input[type=range] codepen, is not aligning correctly with the ticks. It appears to be off by varying amounts (either left or right) depending on the value. Move the handle to see for yourself. What CSS properties ...

Utilizing Typescript to pass props to a material-ui button enclosed in styled-components

After setting up my react project using the typescript template, I decided to style the material-ui Button component using the 'styled' method from the styled-components library as shown below: import React from 'react'; import styled f ...

Get the value of a CSS property in Python by parsing the rendered HTML

Currently, I am using Selenium and PhantomJS in conjunction with Python for the purpose of crawling rendered web pages. While it is a straightforward process to identify the presence of specific words within the HTML content (e.g. if "example" in html...), ...

Having trouble with the tooltip feature in Bootstrap?

I've searched high and low, including on this site! I've experimented with all sorts of code, but nothing seems to make the tooltips function in BootStrap. It's beginning to really frustrate me!! Does anyone happen to have the working js co ...

Are you interested in implementing the switcher function in a React JS class component?

I am having trouble implementing the switcher method in my react app, which is built using class components. Can you provide guidance on how to utilize the useThemeSwitcher() function in class components? How can I integrate this function into my web app ...