{"id":19253252,"url":"https://github.com/pettiboy/javascript-todo-app","last_synced_at":"2025-02-23T17:12:29.637Z","repository":{"id":122474431,"uuid":"514535479","full_name":"pettiboy/javascript-todo-app","owner":"pettiboy","description":"A TODO app using JavaScript for logic and Bootstrap for styling.","archived":false,"fork":false,"pushed_at":"2022-07-22T17:02:09.000Z","size":63,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-05T07:15:07.892Z","etag":null,"topics":["beginner-project","bootstrap","javascript","javascript-project","localstorage","todo-app","todolist"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pettiboy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-16T09:35:12.000Z","updated_at":"2023-07-26T11:43:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"21a0190c-36e6-4a33-8dc1-93cfd18c1f04","html_url":"https://github.com/pettiboy/javascript-todo-app","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pettiboy%2Fjavascript-todo-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pettiboy%2Fjavascript-todo-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pettiboy%2Fjavascript-todo-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pettiboy%2Fjavascript-todo-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pettiboy","download_url":"https://codeload.github.com/pettiboy/javascript-todo-app/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240347980,"owners_count":19787237,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beginner-project","bootstrap","javascript","javascript-project","localstorage","todo-app","todolist"],"created_at":"2024-11-09T18:29:54.291Z","updated_at":"2025-02-23T17:12:29.612Z","avatar_url":"https://github.com/pettiboy.png","language":"JavaScript","readme":"# TODO app using vanilla JavaScript\n\nBuilding a TODO app is a very basic but thorough way to understand concepts of a software tool.\n\nWe will build a TODO app using [`JavaScript`](https://developer.mozilla.org/en-US/docs/Web/JavaScript) for logic and [`Bootstrap`](https://getbootstrap.com/) for styling in this tutorial.\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./assets/screenshot.png\" width=\"250\"/\u003e\n\u003c/p\u003e\n\nTry out the app [`here`](https://pettiboy.github.io/javascript-todo-app/).\n\n## We will follow the following steps:\n\n### Building the `User Interface (UI)` with `Bootstrap`\n\n1. Start with [`Bootstraps Starter Template`](https://getbootstrap.com/docs/5.2/getting-started/introduction/#quick-start)\n\n1. Create a `form` for user to enter the TODO item.\n1. Create an unordered list to `hold all todos`.\n1. Create `list element` with checkbox for a todo item.\n1. Make UI `responsive` using Bootstrap's grid system\n\n### Handling `funtionality` with `JavaScript`\n\n1. Define structure of our data - way to represent all TODOs in a [`JSON (JavaScript Object Notation)`](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON) format.\n1. `renderTodos` function to display TODOs in the UI.\n1. `renderTodo` helper function to render an individual TODO.\n1. `addTodo` function to add a TODO\n1. Setup an Event Listener for `submitting` the todo from the UI.\n1. `completeTodo` function to mark a TODO as completed\n\n## Building UI\n\n##### Copy bootstrap's [starter template](https://getbootstrap.com/docs/5.0/getting-started/introduction/#starter-template) and add custom script tags\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n  \u003chead\u003e\n    \u003c!-- Required meta tags --\u003e\n    \u003cmeta charset=\"utf-8\" /\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\" /\u003e\n\n    \u003c!-- Bootstrap CSS --\u003e\n    \u003clink\n      href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css\"\n      rel=\"stylesheet\"\n      integrity=\"sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC\"\n      crossorigin=\"anonymous\"\n    /\u003e\n\n    \u003ctitle\u003eTODO App\u003c/title\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003c!-- CONTENT --\u003e\n    \u003cdiv\u003e\u003c/div\u003e\n\n    \u003c!-- custom JS --\u003e\n    \u003cscript src=\"./script.js\"\u003e\u003c/script\u003e\n\n    \u003c!-- Bootstrap JS --\u003e\n    \u003cscript\n      src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js\"\n      integrity=\"sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM\"\n      crossorigin=\"anonymous\"\n    \u003e\u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n##### Create a [form](https://getbootstrap.com/docs/5.0/forms/form-control/#sizing) for user to enter the TODO item\n\n- Give unique `id` to `text field` and `form` to refer them in our JavaScript later.\n\n```html\n\u003cform id=\"todo-form\"\u003e\n  \u003c!-- input field --\u003e\n  \u003cinput\n    id=\"todo-text\"\n    class=\"form-control form-control-lg\"\n    type=\"text\"\n    placeholder=\"Your TODO\"\n    required\n  /\u003e\n  \u003c!-- submit button --\u003e\n  \u003cinput type=\"submit\" class=\"btn btn-primary my-3 w-100\" /\u003e\n\u003c/form\u003e\n```\n\n##### Create an unordered list to hold all todos\n\n```html\n\u003cul id=\"todo-list\" class=\"list-unstyled\"\u003e\u003c/ul\u003e\n```\n\n##### Create list element with [checkbox](https://getbootstrap.com/docs/5.0/forms/checks-radios/#checks) for a todo item\n\n```html\n\u003cli\u003e\n  \u003cdiv class=\"form-check\"\u003e\n    \u003cinput class=\"form-check-input\" type=\"checkbox\" /\u003e\n    \u003clabel class=\"form-check-label\" for=\"flexCheckDefault\"\u003e TODO Text \u003c/label\u003e\n  \u003c/div\u003e\n\u003c/li\u003e\n```\n\n##### Make UI responsive using Bootstrap's [grid system](https://getbootstrap.com/docs/5.0/layout/grid/#row-columns)\n\n```html\n\u003cdiv class=\"container\"\u003e\n  \u003cdiv class=\"row row-cols-1 row-cols-sm-1 row-cols-md-2\"\u003e\n    \u003cdiv class=\"col\"\u003e\n      \u003c!-- todo form goes here --\u003e\n    \u003c/div\u003e\n    \u003cdiv class=\"col\"\u003e\n      \u003c!-- todo list goes here --\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\n## Handle functionality using JavaScript\n\n##### Lets start by creating an [array of objects](https://www.freecodecamp.org/news/javascript-array-of-objects-tutorial-how-to-create-update-and-loop-through-objects-using-js-array-methods/) for our `todos`.\n\n```js\nvar todos = [\n  {\n    id: 0,\n    text: \"subscribe to KJSCE codecell\",\n    complete: false,\n  },\n  {\n    id: 1,\n    text: \"Star https://github.com/pettiboy/react-ui-scrollspy on GitHub\",\n    complete: false,\n  },\n];\n```\n\n##### Select all required elements from the `DOM`\n\n```js\nconst list = document.getElementById(\"todo-list\");\nconst form = document.getElementById(\"todo-form\");\nconst todoText = document.getElementById(\"todo-text\");\n```\n\n##### Lets try to render these `todos` to the DOM from our `JS`\n\n```js\n/*\nloops over each todo in todos and if the task is not completed yet\ncalls the renderTodo function to render it to the DOM\n*/\nfunction renderTodos() {\n  emptyTodos();\n  todos.forEach((todo) =\u003e {\n    if (todo.complete === false) {\n      renderTodo(todo);\n    }\n  });\n}\n\n/*\ntakes a todo object as input and appends the innerHTML \nof the unordered list with that todo\n*/\nfunction renderTodo(todo) {\n  list.innerHTML += `\n        \u003cli\u003e\n          \u003cdiv class=\"form-check\"\u003e\n            \u003cinput onclick=\"completeTodo(${todo.id});\" class=\"form-check-input\" type=\"checkbox\" /\u003e\n            \u003clabel class=\"form-check-label\" for=\"flexCheckDefault\"\u003e\n              ${todo.text}\n            \u003c/label\u003e\n          \u003c/div\u003e\n        \u003c/li\u003e\n      `;\n}\n```\n\n##### Lets write a function that given a `todo` adds it to our array of objects called `todos`.\n\n```js\nfunction addTodo(todo) {\n  todos.push({\n    id: todo.id,\n    text: todo.text,\n    complete: todo.complete,\n  });\n\n  // render that todo to the DOM\n  renderTodo(todo);\n}\n```\n\n##### Setup an `Event Listener` for submitting the todo\n\n```js\n// listen for form to be submitted\nform.addEventListener(\"submit\", (e) =\u003e {\n  e.preventDefault();\n\n  addTodo({\n    id: todos.length + 1,\n    text: todoText.value,\n    complete: false,\n  });\n\n  // reset value of input field\n  todoText.value = \"\";\n});\n```\n\n##### Lets write a function to mark a `todo` as `completed`\n\n```js\nfunction completeTodo(removeId) {\n  // Find index of specific object using findIndex method.\n  todoIndex = todos.findIndex((todo) =\u003e todo.id == removeId);\n\n  // Update object's name property.\n  todos[todoIndex].complete = true;\n\n  // Just to wait for a sec before re rendering\n  setTimeout(function () {\n    saveTodosInMemory();\n    renderTodos();\n  }, 1000);\n}\n```\n\n##### Store the todos in `localStorage`\n\n```js\n// on page load - the following functions will run\ntodos = JSON.parse(localStorage.getItem(\"todosInMemory\")) || [];\nrenderTodos();\n```\n\nThat's it! We have successfully built a TODO app using Vanilla JavaScript.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpettiboy%2Fjavascript-todo-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpettiboy%2Fjavascript-todo-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpettiboy%2Fjavascript-todo-app/lists"}