Skip to content

Instantly share code, notes, and snippets.

@jp-resource
Created August 7, 2020 05:33
Show Gist options
  • Save jp-resource/16899a2fa7ce649eba3811767899c389 to your computer and use it in GitHub Desktop.
Save jp-resource/16899a2fa7ce649eba3811767899c389 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/css/bootstrap.min.css" integrity="sha384-VCmXjywReHh4PwowAiWNagnWcLhlEJLA5buUprzK8rxFgeH0kww/aWY76TfkUoSX" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />
<style>
form, #TodoListContainer {
display: flex;
justify-content: center;
align-content: center;
}
.todoList {
margin: 0;
padding: 0;
}
.todoList li {
list-style: none;
display: flex;
background: #0E70C0;
transition: all 0.5s ease;
}
.todoList li span{
flex: 1;
padding: 0 0.5rem;
}
.fa-trash, .fa-check {
pointer-events: none;
}
.completed {
text-decoration: line-through;
opacity: 0.5;
}
.fall {
transform: translate(8rem) rotateZ(20deg);
opacity: 0;
}
select {
-webkit-appearance: none;
appearance: none;
outline: none;
border: none;
}
.select {
margin: 0.8rem;
position: relative;
overflow: hidden;
}
select {
color: #ff6f47;
width: 10rem;
cursor: pointer;
padding: 0.8rem;
}
.select::after {
content: '\25BC';
position: absolute;
background: #ff6f47;
top: 0;
right: 0;
padding: 0.8rem;
pointer-events: none;
}
</style>
</head>
<body>
<form class="form-inline">
<input type="text" class="form-control mb-2 mr-sm-2 todo-input" id="inlineFormInputName2" placeholder="Enter">
<button type="submit" class="btn btn-primary mb-2 todo-btn">Submit</button>
<div class="select">
<select name="todos" class="filter-todo">
<option value="all">All</option>
<option value="completed">Completed</option>
<option value="uncompleted">Uncompleted</option>
</select>
</div>
</form>
<div id="TodoListContainer">
<ul class="todoList"></ul>
</div>
<script>
//Selectors
const todoInput = document.querySelector('.todo-input');
const todoBtn = document.querySelector('.todo-btn');
const todoList = document.querySelector('.todoList');
const filterOption = document.querySelector('.filter-todo');
//Events
document.addEventListener('DOMContentLoaded', getTodos);
todoBtn.addEventListener('click', addTodo);
todoList.addEventListener('click', deleteCheck);
todoList.addEventListener('click', deleteCheck);
filterOption.addEventListener('change', filterTodo);
//Functions
function addTodo(event) {
event.preventDefault();
const todoLi = document.createElement('li');
todoLi.classList.add('todo');
const newTodo = document.createElement('span');
newTodo.innerText = todoInput.value;
newTodo.classList.add('todo-item');
todoLi.appendChild(newTodo);
//add todo to localstorage
saveLocalTodos(todoInput.value);
const completedBtn = document.createElement('button');
completedBtn.innerHTML= '<i class="fas fa-check"></i>';
completedBtn.classList.add('complete-btn');
todoLi.appendChild(completedBtn);
const trashBtn = document.createElement('button');
trashBtn.innerHTML= '<i class="fas fa-trash"></i>';
trashBtn.classList.add('trash-btn');
todoLi.appendChild(trashBtn);
//append to list
todoList.appendChild(todoLi);
todoInput.value= '';
}
function deleteCheck(e){
const item = e.target;
if (item.classList[0] === 'trash-btn') {
let todo = item.parentElement;
todo.classList.add('fall');
removeLocalTodos(todo);
todo.addEventListener('transitionend', function (){
todo.remove();
});
}
if (item.classList[0] === 'complete-btn') {
item.parentElement.classList.toggle('completed');
}
}
//filter function
function filterTodo(e) {
const todos = todoList.childNodes;
todos.forEach(function (todo){
switch (e.target.value) {
case 'all':
todo.style.display ='flex';
break;
case 'completed':
if (todo.classList.contains('completed')) {
todo.style.display = 'flex';
} else {
todo.style.display = 'none';
}
break;
case 'uncompleted':
if (todo.classList.contains('completed')) {
todo.style.display = 'none';
} else {
todo.style.display = 'flex';
}
break;
}
});
}
function saveLocalTodos(todo) {
//check local storage todo
let todos;
if (localStorage.getItem('todos') === null) {
todos = [];
} else {
todos = JSON.parse(localStorage.getItem('todos'));
}
todos.push(todo);
localStorage.setItem('todos', JSON.stringify(todos));
}
function getTodos() {
let todos;
if (localStorage.getItem('todos') === null) {
todos = [];
} else {
todos = JSON.parse(localStorage.getItem('todos'));
}
todos.forEach(function (todo) {
const todoLi = document.createElement('li');
todoLi.classList.add('todo');
const newTodo = document.createElement('span');
newTodo.innerText = todo;
newTodo.classList.add('todo-item');
todoLi.appendChild(newTodo);
const completedBtn = document.createElement('button');
completedBtn.innerHTML= '<i class="fas fa-check"></i>';
completedBtn.classList.add('complete-btn');
todoLi.appendChild(completedBtn);
const trashBtn = document.createElement('button');
trashBtn.innerHTML= '<i class="fas fa-trash"></i>';
trashBtn.classList.add('trash-btn');
todoLi.appendChild(trashBtn);
//append to list
todoList.appendChild(todoLi);
});
}
function removeLocalTodos(todo) {
let todos;
if (localStorage.getItem('todos') === null) {
todos = [];
} else {
todos = JSON.parse(localStorage.getItem('todos'));
}
const todoIndex = todo.children[0].innerText ;
todos.splice(todos.indexOf(todoIndex), 1);
localStorage.setItem('todos', JSON.stringify(todos));
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment