Created
August 13, 2020 14:44
-
-
Save SurenderLohia/94dfaaf430f7b44a5046ba055651cab5 to your computer and use it in GitHub Desktop.
This file contains 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
// IIFE to create local scope and to avoid global namespacing collisions | |
(function () { | |
let todoCollection = {}; | |
let todoIds = []; | |
/* | |
Data Structure: | |
const todoCollection = { | |
"1": { | |
id: 1, | |
task: "HTML", | |
isCompleted: false, | |
}, | |
"2": { | |
id: 2, | |
task: "CSS", | |
isCompleted: false, | |
}, | |
}; | |
const todoIds = [1, 2]; | |
*/ | |
// Localstorage | |
function persistData(key, value) { | |
const valueStirng = JSON.stringify(value); | |
window.localStorage.setItem(key, valueStirng); | |
} | |
function getPersistedData(key) { | |
const value = window.localStorage.getItem(key); | |
return JSON.parse(value); | |
} | |
function init() { | |
const _todoCollection = getPersistedData('todoCollection'); | |
const _todoIds = getPersistedData('todoIds'); | |
if(_todoCollection) { | |
todoCollection = _todoCollection; | |
} | |
if(_todoIds) { | |
todoIds = _todoIds; | |
} | |
if(todoIds.length) { | |
renderTodoList(todoListEl, todoIds, todoCollection); | |
} | |
} | |
// Dom Elements | |
const todoListEl = document.getElementById("js-todo-list"); | |
const addTodoBtn = document.getElementById('js-add-todo-btn'); | |
const addTodoInput = document.getElementById('js-add-todo-input'); | |
const filterTodoRadioBtns = document.querySelectorAll('.js-filter-todo-radio-btn'); | |
const deleteAllBtn = document.getElementById('js-delete-all-btn'); | |
function createListItemEl(todoItem) { | |
return ` | |
<input class="mt0 mb0 mr1" type="checkbox" value="${todoItem.id}" id="${todoItem.id}" ${todoItem.isCompleted ? 'checked': ''} /> | |
${todoItem.task} | |
X | |
`; | |
} | |
function renderTodoList(container, todoIds, todoCollection) { | |
let todoListHTML = ""; | |
todoIds.forEach((id) => { | |
todoListHTML += createListItemEl(todoCollection[id]); | |
}); | |
container.innerHTML = todoListHTML; | |
} | |
function addTodo(task) { | |
const todoId = todoIds.length + 1; | |
const todoItem = { | |
id: todoId, | |
task, | |
isCompleted: false, | |
}; | |
todoCollection[todoId] = todoItem; | |
todoIds.push(todoItem.id); | |
addTodoInput.value = ''; | |
persistData('todoCollection', todoCollection); | |
persistData('todoIds', todoIds); | |
renderTodoList(todoListEl, todoIds, todoCollection); | |
} | |
function toggleTodoItem(id) { | |
todoCollection[id].isCompleted = !todoCollection[id].isCompleted; | |
persistData('todoCollection', todoCollection); | |
} | |
function filterTodoitems(category) { | |
console.log('category', category); | |
if(category === 'all') { | |
renderTodoList(todoListEl, todoIds, todoCollection); | |
return; | |
} | |
let filteredTodoCollection = {} | |
let filteredTodoIds = []; | |
if(category === 'active') { | |
todoIds.forEach((id) => { | |
const todoItem = todoCollection[id]; | |
console.log(todoItem); | |
if(!todoItem.isCompleted) { | |
filteredTodoCollection[id] = todoItem; | |
filteredTodoIds.push(id); | |
} | |
}); | |
} | |
else if(category === 'completed') { | |
todoIds.forEach((id) => { | |
const todoItem = todoCollection[id]; | |
if(todoItem.isCompleted) { | |
filteredTodoCollection[id] = todoItem; | |
filteredTodoIds.push(id); | |
} | |
}); | |
} else { | |
filteredTodoCollection = todoCollection; | |
} | |
renderTodoList(todoListEl, filteredTodoIds, filteredTodoCollection); | |
} | |
function deleteAll() { | |
todoCollection = {}; | |
todoIds = []; | |
persistData('todoCollection', {}); | |
persistData('todoIds', []); | |
renderTodoList(todoListEl, [], {}); | |
} | |
function deleteTodoItem(id) { | |
const todoItemIndex = todoIds.indexOf(Number(id)); | |
delete todoCollection[id]; | |
todoIds.splice(todoItemIndex, 1); | |
persistData('todoCollection', todoCollection); | |
persistData('todoIds', todoIds); | |
renderTodoList(todoListEl, todoIds, todoCollection); | |
} | |
function onAddTodo() { | |
const task = addTodoInput.value; | |
addTodo(task); | |
} | |
// Using EventDelegation: to keep our code simple and performant | |
function onClickTodoItem(e) { | |
const target = e.target; | |
if(target.tagName === 'INPUT') { | |
e.stopPropagation(); | |
const id = target.id; | |
toggleTodoItem(id); | |
} | |
if(target.tagName === 'BUTTON' && target.classList.contains('js-delete-btn')) { | |
e.stopPropagation(); | |
const id = target.getAttribute('data-id'); | |
deleteTodoItem(id); | |
} | |
} | |
function onFilterTodoItems(e) { | |
e.stopPropagation(); | |
const category = e.target.value; | |
filterTodoitems(category); | |
} | |
function onDeleteAll() { | |
deleteAll(); | |
} | |
init(); | |
// AttachEvents | |
addTodoBtn.addEventListener('click', onAddTodo, false); | |
todoListEl.addEventListener('click', onClickTodoItem, false); | |
filterTodoRadioBtns.forEach((item) => { | |
item.addEventListener('input', onFilterTodoItems, false); | |
}); | |
deleteAllBtn.addEventListener('click', onDeleteAll, true); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment