Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

To do day2 #2

Merged
merged 11 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 39 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,63 @@
![](https://img.shields.io/badge/Microverse-blueviolet)
# To Do List

# Webpack Templte
Application that record the tasks to remind you and got many features that you might need.

Additional description about the project and its features.
## This is an image for it

## Live Demo
[Live Demo Here](https://omar25ahmed.github.io/Omar-Ragheb-First-Capstone/)




## Built With

- HTML
- CSS
- Markdown
- JavaScript

## Prerequisites

- text-editor
- git
- github

## Getting Started

after cloneing
**To Create A Portfolio from this Repository feel free to contact me.**

```
npm install
npm start
```
**To get a local copy up and running follow these simple steps.**
- you can clone this repo by typing `git clone git@github.com:omar25ahmed/Omar-Ragheb-ToDo-List`.
- type `cd ToDo List` to access the project on terminal.

## Authors

👤 **Author1**
👤 **Omar Ragheb**

- - GitHub: [@omar25ahmed](https://github.com/omar25ahmed)

- GitHub: [@ahmedta](https://github.com/ahmedta)
- Twitter: [@\_ahmedta](https://twitter.com/_ahmedta)

## 🤝 Contributing

Contributions, issues, and feature requests are welcome!

Feel free to check the [issues page](../../issues/).
Feel free to check the [issues page](https://github.com/omar25ahmed/Portfolio-setup-and-mobile-version-skeleton/issues).

## Show your support

Give a ⭐️ if you like this project!

## Acknowledgments

- Cindy Shin's design
- SciComm [Link](https://www.scicommcon.org/)
- Aspen Global Congress on Scientific Thinking & Action [Link](https://www.aspeninstitute.org/programs/science-society/global-science-congress/)
- Microverse Team

## 📝 License

This project is [MIT](./MIT.md) licensed.

- GitHub: [@omar25ahmed](https://github.com/omar25ahmed)
15 changes: 15 additions & 0 deletions src/class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default class Task {
constructor(description, index) {
this.description = description;
this.completed = false;
this.index = index;
}

set updatedIndex(newIndex) {
this.index = newIndex;
}

set updatedDesc(newDesc) {
this.description = newDesc;
}
}
22 changes: 20 additions & 2 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,29 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wbpackdede Exercise</title>
<title>To Do List</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css">
<link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@1,300&display=swap" rel="stylesheet">
<script src="https://kit.fontawesome.com/4f5822c69a.js" crossorigin="anonymous"></script>
</head>

<body>
<h1>Hello w!</h1>
<div class="container">
<div class="header">
<p>Today's To Do</p>
<button type="button" class="fas fa-sync-alt"></button>
</div>
<hr>
<form class="todo-add">
<input type="text" class="form-field" placeholder="Add to your list..."/>
<button type="submit" class="fas fa-level-down-alt"></button>
</form>
<ul class="todo-list" id="todo-list">
</ul>
<div class="footer">
<button type="button" class="todo-clear">Clear all completed</button>
</div>
</div>
</body>

</html>
127 changes: 119 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,125 @@
import _ from 'lodash';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When adding or deleting a task from your to-do list its important that the tasks property index is always set to the value of the new array length.

Captura

As you can see in the image, After playing around adding, deleting, and editing tasks, the left task index is 3 when it should be 1. Kindly make the necessary changes to that your app works as mentioned 🔥

The mentioned issue with the indexes of your tasks is causing another one. If you create a single task and you remove it, works perfectly. If you create a bunch of tasks and then delete the first-created ones until only the last one is left and you try to delete it doesn't work properly. After the page is refreshed, the task is still there. I assume its something to do with the index not matching the one you think you are removing 👀

import './style.css';
import Task from './class.js';

function component() {
const element = document.createElement('div');
const form = document.querySelector('.todo-add');
const input = document.querySelector('.form-field');
const ul = document.getElementById('todo-list');
let li;

// Lodash, now imported by this script
element.innerHTML = _.join(['Hello', 'ahmed'], ' ');
element.classList.add('hello');
let tasks = [];

return element;
function getTasks() {
if (localStorage.getItem('tasks') == null) {
tasks = [];
} else {
tasks = Array.from(JSON.parse(localStorage.getItem('tasks')));
}
return tasks;
}

document.body.appendChild(component());
function prepareEdit(task, btn) {
btn.addEventListener('click', () => {
const el = document.querySelector(`[data-index="${task.index}"]`);
const p = el.children[1];
const input = document.createElement('input');
input.type = 'text';
input.value = p.textContent;
input.id = task.index;
el.insertBefore(input, p);
el.removeChild(p);
input.focus();
input.select();
input.classList.add('edit');
});
}
Comment on lines +20 to +34

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I like the way you implemented the edit. However, when I edit a task, the edited description is not saved to the localStorage, so when I reload the page, it shows undefined as the value for the description. What you want to do is to edit the value of the description and save the array with the edited value to the localStorage.

Hint: You should filter through the array, select that particular object, set the value of the description key of that object to the input value then save the whole array to the local storage.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏽 This works fine now


function loadTasks() {
const tasks = Array.from(JSON.parse(localStorage.getItem('tasks')));
tasks.forEach((task) => {
li = document.createElement('li');
li.classList.add('task-li');
li.innerHTML = `
<div class="task" data-index="${task.index}">
<input type="checkbox">
<p>${task.description}</p>
<div class="btns">
<button type="button" class="close-button scroll">+</button>
<button type="button" class="fas fa-ellipsis-v scroll" id="edit-${task.index}"></button>
</div>
</div>
`;
ul.appendChild(li);
const btn = document.getElementById(`edit-${task.index}`);
prepareEdit(task, btn);
localStorage.setItem('tasks', JSON.stringify(tasks));
// getTasks();
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Kindly remove all codes that are commented out. Removing such codes makes your code look clean.

}

function addTask() {
ul.innerHTML = '';
tasks.forEach((task) => {
li = document.createElement('li');
li.classList.add('task-li');
li.innerHTML = `
<div class="task" data-index="${task.index}">
<input type="checkbox">
<p>${task.description}</p>
<div class="btns">
<button type="button" class="close-button scroll">+</button>
<button type="button" class="fas fa-ellipsis-v scroll" id="edit-${task.index}"></button>
</div>
</div>
`;
ul.appendChild(li);
const btn = document.getElementById(`edit-${task.index}`);
prepareEdit(task, btn);
localStorage.setItem('tasks', JSON.stringify(tasks));
// getTasks();
console.log(tasks);
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Kindly remove all codes that are commented out. Removing such codes makes your code look clean.
  • Kindly remove the console.log function in your code. It is a best practice to remove all console.log statements from your code so that you do not reveal sensitive information to visitors of your site.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏽 This has been implemented also

}

function removeTask(e) {
if (e.target.classList.contains('close-button')) {
const deletedIndex = e.target.parentElement.parentElement.dataset.index;
const toBeUpdatedTasks = tasks.slice(deletedIndex, tasks.length);
toBeUpdatedTasks.forEach((task) => {
const el = document.querySelector(`[data-index="${task.index}"]`);
el.dataset.index = task.index - 1;
task.updatedIndex = task.index - 1;
});
Comment on lines +73 to +75

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I can see that you are trying to implement changes from the previous reviewer. You do not need to add an updatedIndex key when you delete an item, all that is required for you is to rearrange the values of the index key of each object in the array.

Hint:

const filteredArray = array.filter((obj) => obj.completed !== true);
    filteredArray.forEach((obj, index) => {
      obj.index = index + 1;
    })

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍🏽 This works fine now

e.target.parentElement.parentElement.remove();
tasks.splice(deletedIndex - 1, 1);
}
localStorage.setItem('tasks', JSON.stringify(tasks));
// getTasks();
console.log(tasks);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Kindly remove all codes that are commented out. Removing such codes makes your code look clean.

}

form.addEventListener('submit', (e) => {
e.preventDefault();
const task = new Task(input.value, tasks.length + 1);
tasks.push(task);
addTask();
input.value = '';
});

ul.addEventListener('click', removeTask);

ul.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
const task = tasks.find((t) => t.index === parseInt(e.target.id, 10));
task.updatedDesc = e.target.value;
const p = document.createElement('p');
p.textContent = e.target.value;
const parent = document.querySelector(`[data-index="${e.target.id}"]`);
parent.insertBefore(p, e.target);
parent.removeChild(e.target);
task.description = task.updatedDesc;
localStorage.setItem('tasks', JSON.stringify(tasks));
getTasks();
}
});

window.onload = loadTasks;
105 changes: 103 additions & 2 deletions src/style.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,104 @@
.hello {
color: blue;
body {
background-color: #f6f6f6;
}

.container {
border: 1px solid;
background-color: #fff;
width: 50%;
margin: auto;
}

.header {
display: flex;
justify-content: space-between;
padding: 10px;
}

.header button {
background-color: transparent;
border: none;
cursor: pointer;
}

.todo-add {
display: flex;
padding: 10px;
}

.todo-add button {
background-color: transparent;
border: none;
cursor: pointer;
}

.form-field {
font-family: inherit;
width: 100%;
border: 0;
border-bottom: 2px solid #9b9b9b;
outline: 0;
font-size: 1.3rem;
color: black;
padding: 7px 0;
background: transparent;
transition: border-color 0.2s;
}

ul {
list-style: none;
padding: 10px;
}

.task {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 10px;
}

.btns {
margin-left: auto;
display: flex;
gap: 40px;
}

.close-button {
transform: rotate(45deg);
cursor: pointer;
font-size: 30px;
color: red;
}

.edit {
border-color: transparent;
height: 40px;
}

.edit:focus-visible {
outline: green auto 1px;
font-size: 15px;
}

.scroll {
background-color: transparent;
border: none;
cursor: pointer;
margin-left: auto;
}

.footer {
background-color: #f6f6f6;
height: 50px;
border-top: 1px solid;
display: flex;
justify-content: center;
opacity: 0.5;
}

.footer button {
background-color: transparent;
border: none;
cursor: pointer;
font-size: 20px;
}