Last active
January 18, 2026 22:59
-
-
Save JasonKaz/ead463e3c8ed60acbe400c20e331aa6f to your computer and use it in GitHub Desktop.
Basic todo app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <html> | |
| <head> | |
| <title>Todo list app</title> | |
| </head> | |
| <body> | |
| <div id="app"> | |
| <input type="text" id="project-name" placeholder="New Project Name"> | |
| <button onclick="newProject(document.getElementById('project-name').value)">Add</button> | |
| <div id="projects-and-tasks"></div> | |
| </div> | |
| <script> | |
| const save = () => { | |
| localStorage.setItem('todoData', JSON.stringify(data)); | |
| }; | |
| const load = () => { | |
| const savedData = localStorage.getItem('todoData'); | |
| if (savedData) { | |
| const parsedData = JSON.parse(savedData); | |
| return parsedData; | |
| } | |
| return []; | |
| }; | |
| const data = load(); | |
| const newProject = (name) => { | |
| console.log(data); | |
| const newId = data.length; | |
| data.push({ id: newId, name: name, tasks: [] }); | |
| render(); | |
| save(); | |
| }; | |
| const newTask = (projectId, description) => { | |
| const project = data.find(p => p.id === projectId); | |
| if (project) { | |
| const newTaskId = project.tasks.length; | |
| project.tasks.push({ id: newTaskId, description, completed: false }); | |
| } | |
| render(); | |
| save(); | |
| }; | |
| const updateTaskStatus = (projectId, taskId, completed) => { | |
| const project = data.find(p => p.id === projectId); | |
| if (project) { | |
| const task = project.tasks.find(t => t.id === taskId); | |
| if (task) { | |
| task.completed = completed; | |
| } | |
| } | |
| render(); | |
| save(); | |
| }; | |
| const render = () => { | |
| const container = document.getElementById('projects-and-tasks'); | |
| container.innerHTML = ''; | |
| data.forEach(project => { | |
| const projectDiv = document.createElement('div'); | |
| projectDiv.innerHTML = `<h3>${project.name}</h3> | |
| <input type="text" id="task-desc-${project.id}" placeholder="New Task Description"> | |
| <button onclick="newTask(${project.id}, document.getElementById('task-desc-${project.id}').value); render();">Add Task</button> | |
| <ul id="task-list-${project.id}"></ul>`; | |
| const taskList = projectDiv.querySelector(`#task-list-${project.id}`); | |
| project.tasks.forEach(task => { | |
| const taskItem = document.createElement('li'); | |
| const checkbox = document.createElement('input'); | |
| checkbox.type = 'checkbox'; | |
| checkbox.id = `task-${project.id}-${task.id}`; | |
| checkbox.checked = task.completed ? 'checked' : ''; | |
| taskItem.appendChild(checkbox); | |
| taskItem.appendChild(document.createTextNode(` ${task.description}`)); | |
| taskList.appendChild(taskItem); | |
| checkbox.addEventListener('click', function() { | |
| updateTaskStatus(project.id, task.id, this.checked); | |
| }); | |
| }); | |
| container.appendChild(projectDiv); | |
| }); | |
| }; | |
| render(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment