Build a Todo App using Local Storage - Step 36 not passing accessibility screen reader challenges

hi, doing the build a to do list app. and now totally blind and using a screen reader, jaws, nvda and windows narrator. when i have extra spaces or stray characters at the end of my code, then by googling and trying to figure that out, then it does not tell me the stray character and does not say e or something else, just blank. and tried that with jaws 2026, nvda 2025.3 and windows narraotr windows 11 pro 2025 latest update. so, now doing step 36, i have the for each feature of the function moved into the task data function, but fcc is being very stubborn. and not passing, so, reset the lesson, did a hard refresh, rewrote the code for the function, but still not passing, you need to improve the accessibility of the editor for screen reader users, maybe a special module or some accessibility settings, and then detects that i am using a screen reader, says for example you need to then move the for each function, maybe what if any stray characters and tells me if any hidden characters or hidden spacing or hidden and on which line, that would help a lot of blind developers and this project is going to take me at least 2 months whith accessibility challenges and roadblocks. rant over. so if quincy is seeing this or a lead mod who can make the changes, very frustrating when you cannot see, try writing code with your eyes closed and using a screen reader and the keyboard. you dont know, as you cannot walk in my shoes. defintely rant over.

marvin.

ps: pasting my code, the error message and a link to the step.

any help.

i know my code is fine, did double check with an example i found online to check if my code is the issue, no it is fcc code checker. and very frustrating after multiple resets, refreshes and multiple rewrites of the code. no wonder getting frustrated.

java script:

// — DOM elements —

const taskForm = document.getElementById(“task-form”)

const confirmCloseDialog = document.getElementById(“confirm-close-dialog”)

const openTaskFormBtn = document.getElementById(“open-task-form-btn”)

const closeTaskFormBtn = document.getElementById(“close-task-form-btn”)

const cancelBtn = document.getElementById(“cancel-btn”)

const discardBtn = document.getElementById(“discard-btn”)

const tasksContainer = document.getElementById(“tasks-container”)

const titleInput = document.getElementById(“title-input”)

const dateInput = document.getElementById(“date-input”)

const descriptionInput = document.getElementById(“description-input”)

// — Data store —

const taskData =

let currentTask = {}

// — Functions —

const reset = () => {

titleInput.value = “”

dateInput.value = “”

descriptionInput.value = “”

taskForm.classList.add(“hidden”)

currentTask = {}

}

const addOrUpdateTask = () => {

const index = taskData.findIndex(task => task.id === currentTask.id)

const task = {

id: titleInput.value.toLowerCase().split(" ").join("-") + "-" + Date.now(),

title: titleInput.value,

date: dateInput.value,

description: descriptionInput.value

}

if (index === -1) taskData.unshift(task)

}

// — Step 36: update tasks container —

const updateTaskContainer = () => {

tasksContainer.innerHTML = “”

taskData.forEach(task => {

tasksContainer.innerHTML +=

  '<div class="task" id="' + task.id + '">' +

    '<p><strong>Title:</strong> ' + task.title + '</p>' +

    '<p><strong>Date:</strong> ' + task.date + '</p>' +

    '<p><strong>Description:</strong> ' + task.description + '</p>' +

    '<button type="button" class="btn">Edit</button>' +

    '<button type="button" class="btn">Delete</button>' +

  '</div>'

})

}

// — Event listeners —

openTaskFormBtn.addEventListener(“click”, () => taskForm.classList.toggle(“hidden”))

closeTaskFormBtn.addEventListener(“click”, () => {

if (titleInput.value || dateInput.value || descriptionInput.value) {

confirmCloseDialog.showModal()

} else {

reset()

}

})

cancelBtn.addEventListener(“click”, () => confirmCloseDialog.close())

discardBtn.addEventListener(“click”, () => {

confirmCloseDialog.close()

reset()

})

taskForm.addEventListener(“submit”, e => {

e.preventDefault()

addOrUpdateTask()

updateTaskContainer()

reset()

})

errors:

Sorry, your code does not pass. Keep trying.

You should move taskData.forEach() and its content into the updateTaskContainer() function.

link to the step:

You some how altered the tasksContainer.innerHTML by removing the two backticks, then adding single quote marks around each element and concatenating them with the plus sign.

The rest of the code is fine. I managed to cut and paste the required code into the code you posted, and after a few minor adjustments, the code passed.

Please reset the step. Select and cut the required code, add the arrow syntax function then paste the code into the new function.

Happy coding

hi, have reset the lesson, done hard refreshes, but i think theres a bug with the code for step 36. says to then move it into the function, but i have done that. so going to then share my code snippet, and then the error message. using jaws 2026. screen reader, so have rewritten the function once or twice. so have tried a few different trouble shooting. but not passing, so what tweeks did you use to get it to pass? have tried and also googled and the code looks the same or similar. so dont want you to give me the code, thats not the point of learning, but having accessbiility challenges as a screen reader user. so can you maybe post on github if it is a bug with fcc. and so just frustrated and taking me about more then 24 hours apart from sleep, food etc, to then try to get this to work. so, can you help me out. so i then can get this to pass. do have a local copy of the file in vs code. so just banging my head against a brick wall. fcc is very strict. pity is was not a little more loose. so just my two cents. so have to wait as in adelaide, australia, and with the time zones in the us, 15.5 hours ahead in new york, and 18.5 hours ahead of los angelos. so, just want this to pass. have tried all troubleshooting steps. unless something i am missing. also using google chrome latest version, windows 11 2025. adn latest version of jaws and also nvda. 2025.3. so if theres hidden characters or hidden trailling spaces, my screen reader is not picking it up. and also there was some stray characters at the bottom of my script, but then jaws, nvda, windows narrator did not see that character, so had to guess and then use right arrow and delete, then hope it was gone. so, fcc needs some accessibility tweeking, was not built for blind developers using a screen reader. so pasting my code snippet below and the error message.

java script:

const taskForm = document.getElementById(“task-form”);
const confirmCloseDialog = document.getElementById(“confirm-close-dialog”);
const openTaskFormBtn = document.getElementById(“open-task-form-btn”);
const closeTaskFormBtn = document.getElementById(“close-task-form-btn”);
const addOrUpdateTaskBtn = document.getElementById(“add-or-update-task-btn”);
const taskContainer = document.getElementById(“task-container”);

let taskData = JSON.parse(localStorage.getItem(“data”)) || ;
let currentTask = {};

openTaskFormBtn.addEventListener(“click”, () => {
taskForm.classList.remove(“hidden”);
});

closeTaskFormBtn.ad

errors:

Sorry, your code does not pass. You’re getting there.

You should move taskData.forEach() and its content into the updateTaskContainer() function.

thank you.

marvin..

The modification I made included changing curly quote marks to straight quote marks.

The other change was reinserting an empty array, the [] was missing from the code.

The other one was tasksContainer.innerHTML was modified, so I either changed it back or copied the original code and pasted it into your code.

Can you please post your full code?

Happy coding

hi, heres my html, css and js.

pasting below:

html:

body {

font-family: Arial, sans-serif;

margin: 20px;

}

header {

display: flex;

justify-content: space-between;

align-items: center;

margin-bottom: 20px;

}

button {

cursor: pointer;

padding: 5px 10px;

margin: 5px;

}

#task-form {

border: 1px solid #ccc;

padding: 15px;

margin-bottom: 20px;

display: flex;

flex-direction: column;

gap: 10px;

}

#task-form.hidden {

display: none;

}

.task {

border: 1px solid #ccc;

padding: 10px;

margin-bottom: 10px;

}

.task p {

margin: 5px 0;

}

.edit-btn {

background-color: #4CAF50;

color: white;

}

.delete-btn {

background-color: #f44336;

color: white;

}

dialog {

border: 1px solid #ccc;

padding: 20px;

}

dialog button {

margin-right: 10px;

}

java script:

// --- ELEMENTS ---
const taskForm = document.getElementById("task-form");
const confirmCloseDialog = document.getElementById("confirm-close-dialog");
const openTaskFormBtn = document.getElementById("open-task-form-btn");
const closeTaskFormBtn = document.getElementById("close-task-form-btn");
const cancelBtn = document.getElementById("cancel-btn");
const discardBtn = document.getElementById("discard-btn");
const tasksContainer = document.getElementById("tasks-container");
const titleInput = document.getElementById("title-input");
const dateInput = document.getElementById("date-input");
const descriptionInput = document.getElementById("description-input");

// --- DATA ---
const taskData = [];
let currentTask = {};

// --- FUNCTIONS ---
const addOrUpdateTask = () => {
  if (!titleInput.value) return;

  const index = taskData.findIndex(item => item.id === currentTask.id);

  const task = {
    id: currentTask.id || `${titleInput.value.toLowerCase().split(" ").join("-")}-${Date.now()}`,
    title: titleInput.value,
    date: dateInput.value,
    description: descriptionInput.value
  };

  if (index === -1) taskData.unshift(task);
  else taskData[index] = task;
};

const reset = () => {
  titleInput.value = "";
  dateInput.value = "";
  descriptionInput.value = "";
  taskForm.classList.add("hidden");
  currentTask = {};
};

// --- FCC expects this exact format ---
const updateTaskContainer = () => {
  tasksContainer.innerHTML = "";

  taskData.forEach(task => {
    const taskDiv = document.createElement("div");
    taskDiv.className = "task";
    taskDiv.id = task.id;

    taskDiv.innerHTML = `
      <p><strong>Title:</strong> ${task.title}</p>
      <p><strong>Date:</strong> ${task.date}</p>
      <p><strong>Description:</strong> ${task.description}</p>
      <button type="button" class="edit-btn">Edit</button>
      <button type="button" class="delete-btn">Delete</button>
    `;

    // Edit button listener inside loop
    taskDiv.querySelector(".edit-btn").addEventListener("click", () => {
      currentTask = taskData.find(t => t.id === task.id);
      titleInput.value = currentTask.title;
      dateInput.value = currentTask.date;
      descriptionInput.value = currentTask.description;
      taskForm.classList.remove("hidden");
    });

    // Delete button listener inside loop
    taskDiv.querySelector(".delete-btn").addEventListener("click", () => {
      const index = taskData.findIndex(t => t.id === task.id);
      if (index !== -1) {
        taskData.splice(index, 1);
        updateTaskContainer();
      }
    });

    tasksContainer.appendChild(taskDiv);
  });
};

// --- EVENTS ---
openTaskFormBtn.addEventListener("click", () => taskForm.classList.remove("hidden"));

closeTaskFormBtn.addEventListener("click", () => {
  if (titleInput.value || dateInput.value || descriptionInput.value) confirmCloseDialog.showModal();
  else reset();
});

cancelBtn.addEventListener("click", () => confirmCloseDialog.close());

discardBtn.addEventListener("click", () => {
  confirmCloseDialog.close();
  reset();
});

taskForm.addEventListener("submit", e => {
  e.preventDefault();
  addOrUpdateTask();
  updateTaskContainer();
  reset();
});

and why it is failing. something wrong i am doing, and then screen readers read the curly quotes as "", cannot distinct unless i then have to go into the jaws dictionary manager and then add certain like "" and so, trying my best, and so if you can help me out. dont want the exact code, thats not the point of learning, so trying my best, writing the code, trying things, trying to trouble shoot and the code does work, able to then add a task, put in a title, description, add the date picker, able to edit a task and then able to delete, when adding a task and clicking add task, it shows me the list of tasks. so i know it works, fcc automated tests being very picky and maybe the format or the functions it looks for. so in adelaide, australia. and so if you can help me out. trying my best. and found the code from searching on an example on google.   

Hi @BlindVisionMan

taskData.forEach() was modified.

Please reset the step to restore the original code.

You also included code that was not asked for in the instructions.

taskData.forEach() is thirteen lines of code only.

The JavaScript file was the only code I needed. It was correctly formatted.

Happy coding

the curly quotes appear in the forum when you paste code without using codeblocks, that’s one of the reasons we ask you try to use code blocks to format the code, so the code stay the same as the code you have in the editor

if you can’t find the backticks in your post anymore, now the post has two modes, a rich editor one, and a plain text one, you should be able to switch between the two using Ctrl + M. If you can’t find the backticks anymore the editor could be in rich text mode

hi, heres my html. sorry, did not put that in, my mistake, should have double checked . thought i had. so heres it is:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>FCC To-Do App</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <header>
    <h1>To-Do App</h1>
    <button id="open-task-form-btn">Add New Task</button>
  </header>

  <!-- Task Form -->
  <form id="task-form" class="hidden">
    <label>
      Title:
      <input type="text" id="title-input" required>
    </label>
    <label>
      Date:
      <input type="date" id="date-input">
    </label>
    <label>
      Description:
      <textarea id="description-input"></textarea>
    </label>
    <button type="submit" id="add-or-update-task-btn">Add / Update Task</button>
    <button type="button" id="close-task-form-btn">Close</button>
  </form>

  <!-- Confirmation Dialog -->
  <dialog id="confirm-close-dialog">
    <p>Discard changes?</p>
    <button id="cancel-btn">Cancel</button>
    <button id="discard-btn">Discard</button>
  </dialog>

  <!-- Tasks Container -->
  <section id="tasks-container"></section>

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


ps: so how to get this step to pass, it could be a bug with the fcc, please help me out.

hi, so then i dont have to tab 1500 times to the preformatted code, thought i was doing that when doing control e, thought that was the short cut for doing the preformatted text. your forum is not the easiest to navigate and then find the correct toolbar. and using jaws.

marvin.

Ctrl E creates the code blocks, that’s correct. Ctrl M changes between the two modes of the editor, Rich Text was added in one of the software updates, and activated by default for everyone, you can switch back to the other mode with Ctrl M.

Now, was there something you do not understand from Teller message?

hi i did not know about control m switching, thanks. did not know that. and yes, did understand from tellers post. now just waiting for his help to try to get step 36 to pass.

marvin.

hi, this is a long shot. is there a way to go back to a more accessible fcc editor or a classic editor. probably not, but asking, as having accessibility challenges and maybe some accessibility hacks for blind developers like i posted the other day. okay patiently waiting for your help, how to pass step 36. and just being very strict the checker or just being stubborn and heard that sighted users struggling with this step as well. no wonder almost tearing out my hair.

the freeCodeCamp editor for workshop has never been different. There is a new version coming out in the future tho

anyway, pleae go back to Teller post and read it, there are some tips you did not try, here the link for you: Build a Todo App using Local Storage - Step 36 not passing accessibility screen reader challenges - #6 by Teller

hi teller i did try that with the quotes and the array and then didd try that, still not working. so what am i stupidly doing wrong? can you help me out so to get this to pass. frustrated and cannot see if more hidden characters, or stray characters or hidden spacing.and using a screen reader and the keyboard. so facing accessibility hurdles with the editor. marvin.

I am copying below Teller’s post, please check it out again