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

Exercises-1 pull req Dan Menahem #6

Open
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

DanMenahem
Copy link

No description provided.

</div>
<div id="info">
<span id="peding-task-text">You have 0 pending tasks</span>
<button class="btn" id="clearAllBtn" disabled>Clear All</button>

Choose a reason for hiding this comment

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

Good job on reusing the btn class!

* {
font-family: Alef, Arial, Helvetica, sans-serif;
font-size: 20px;
margin: 0;

Choose a reason for hiding this comment

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

in general, it's usually a bad practice to use the wildcard selector *, as it applies to all elements, rather than inheriting the style from a parent element (it still could be html or body) which are much easier to override when needed.
You can read more on CSS precedence here - https://jenkov.com/tutorials/css/precedence.html

You also have this cool library that normalizes the base/default styles across different browsers - https://necolas.github.io/normalize.css/

.btn[disabled] {
opacity: 0.3;
box-shadow: none;
border: none;

Choose a reason for hiding this comment

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

duplicate? isn't it already in .btn?


.btn[disabled]:hover {
cursor: not-allowed;
box-shadow: none;
Copy link

@SergeiSafrigin SergeiSafrigin May 27, 2022

Choose a reason for hiding this comment

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

duplicate? isn't it already in .btn[disabled]? (move below .btn:hover)

box-shadow: none;
}

.btn {

Choose a reason for hiding this comment

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

it's a good practice to put all the different variants of a style after the base is defined so the variants will get a priority and could override the base class with ease and without the need for !important

}


#taskList li {

Choose a reason for hiding this comment

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

Using "li" here instead of a class makes it coupled to this specific solution. If you'll need to change li to a different element (ex: div) you'll have to make many changes in the code

overflow: hidden;
}

#taskList li span {
Copy link

@SergeiSafrigin SergeiSafrigin May 27, 2022

Choose a reason for hiding this comment

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

The same goes for the span here better to use a class name. Also for readability, a descriptive classname will tell me on which element this style is targeting

const addBtn = document.querySelector(" #addBtn ");
const clearAllBtn = document.querySelector(" #clearAllBtn ");
const sortAllBtn = document.querySelector(" #sortAllBtn ");
const taskList = document.querySelector(" #taskList ");

Choose a reason for hiding this comment

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

having all the elements outside here requires all the dom elements exist when this file is loaded, which might not be the case in complex web apps that dynamically change the dom depending on the view

const placeHolder = document.querySelector(" .placeHolder ")
const pedingTaskText = document.querySelector(" #peding-task-text ")

const taskArr = JSON.parse(localStorage.getItem("tasks")) || [];

Choose a reason for hiding this comment

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

nice!
consider moving this to a function that handles the initial loading of the tasks



//waiting for user input before enable the add button
taskInput.addEventListener('keyup', () => addBtn.disabled = !taskInput.value)

Choose a reason for hiding this comment

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

extract the validation into a function as multiple sources need to use it :)


//sort the tasks list add them to html list element and save them to the LocalStorage
sortAllBtn.addEventListener("click", () => {
taskArr.sort();

Choose a reason for hiding this comment

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

the sort method mutates the original array, therefore it's better to copy it beforehand ex: taskArr = [...taskArr.sort()];

As mutating the state directly (and complex data structures in general) is considered a bad practice as other parts of the code might be using it, not expecting it to suddenly change.
Read more on pure functions and the immutability approach in coding https://css-tricks.com/understanding-immutability-in-javascript/


//Clear the tasks list
clearAllBtn.addEventListener("click", () => {
taskArr.length = 0;
Copy link

@SergeiSafrigin SergeiSafrigin May 27, 2022

Choose a reason for hiding this comment

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

not a common usage, I would change it to taskArr = [];
Also it mutates taskArr directly which is a bad practice due to the comment above

//if there are some task in the localStorage insert them
function init() {
if (taskArr.length != 0) insertAllTasks();
else placeHolder.classList.remove("hidden");

Choose a reason for hiding this comment

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

code duplication, this could have been instead a call to showEmptyState()/ showEmptyStateIfNeeded()/toggleEmptyState() or something similar

}

//Function to create the li element and its childs and assign a click event to them
function createLi(taskValue) {

Choose a reason for hiding this comment

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

same as the css point, let's decouple this by changing to something more general like createTaskElement/createTaskNode

}

//if there are some task in the localStorage insert them
function init() {

Choose a reason for hiding this comment

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

nice use of init, I would add the loading of the localStorage and initializing the tasksList here as well

i.classList.add("fa", "fa-trash-o");
span.appendChild(i);
li.appendChild(span);
span.onclick = (e) => {

Choose a reason for hiding this comment

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

prefer using the addEventListener instead of onclick directly

}

//update the button and the placeHolder if necessary
function updateForm() {

Choose a reason for hiding this comment

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

Consider renaming the function to make it more descriptive or even separate into 2 different functions as you always know what you actually need to do beforehand. 1 for hiding the empty state and other for showing it


// function to remove task that have been clicked
function removeTask(li, taskValue) {
taskArr.splice(taskArr.indexOf(taskValue), 1);

Choose a reason for hiding this comment

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

As task holds only the text value it is not unique, therefore you might be removing the wrong task from the list. Consider an alternative approach. hint: find a way to uniquely identify tasks

<title>Exercise 1</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

Choose a reason for hiding this comment

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

nice

<i class="fa fa-plus"></i>
<p>Time to add your first task</p>
</div>
<div id="info">

Choose a reason for hiding this comment

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

Good dom modeling, gj!

Copy link

@SergeiSafrigin SergeiSafrigin left a comment

Choose a reason for hiding this comment

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

see comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants