diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae8e54b --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# TaskListJS +Task List in vanilla JS diff --git a/index.html b/index.html index e69de29..54bb03c 100644 --- a/index.html +++ b/index.html @@ -0,0 +1,58 @@ + + + + + + Task List + + + + +
+

Task List

+ +
+ + + + + +
menu
+ + +

Tasks

+ + + + +
+ +
+ + + + + + + + + \ No newline at end of file diff --git a/index.js b/index.js index e69de29..89f30a7 100644 --- a/index.js +++ b/index.js @@ -0,0 +1,176 @@ + +const form = document.getElementsByClassName('addTaskForm')[0]; + +const focusDiv = document.getElementsByClassName('focusDiv')[0]; +const addTaskBtn = document.getElementById('addTaskBtn'); +const tasks = document.getElementById('tasks'); + +let hideBtn = document.getElementsByClassName('hideMenu')[0]; +let menu = document.getElementsByClassName('menu')[0]; + +const hideCompleteBtn = menu.children[0]; +const deleteCompleteBtn = menu.children[1]; +const showAllBtn = menu.children[2]; +const sortNameBtn = document.getElementsByClassName('sortByName')[0]; +const sortDateBtn = document.getElementsByClassName('sortByDate')[0]; + +const taskBoilerplate = document.getElementsByClassName('taskBoilerplate')[0]; + +if(!localStorage.tasks){ + localStorage.tasks = '[]'; +} +let TaskData = (JSON.parse(localStorage.tasks)) || []; + +if(TaskData.length != 0){ + showTasks(TaskData); + showSortBtns(); +} + + + + +function updateLocal(tasks){ + localStorage.setItem('tasks',JSON.stringify(tasks)); +} +function showMenu(){ + menu.style.top = '-10px'; + hideBtn.style.display = 'block'; +} + +function hideMenu(){ + menu.style.top = '-140px'; + hideBtn.style.display = 'none' +} + +function clearTasksDiv(){ + while(tasks.firstChild)tasks.removeChild(tasks.firstChild); +} +function showTasks(taskArr){ + clearTasksDiv(); + taskArr.map(task => { + const taskDiv = taskBoilerplate.cloneNode(true); + const title = taskDiv.children[0]; + const description = taskDiv.children[1]; + const complete = taskDiv.children[2].children[0]; + const id = taskDiv.children[3]; + + id.innerHTML = task.Id; + title.innerHTML = task.Task; + description.innerHTML= task.Description; + complete.checked = task.complete; + + taskDiv.style.display = 'flex'; + + tasks.append(taskDiv); + showSortBtns(); + return; + }); +} + +const deleteTask = (e) => { + let target = e.target; + let taskId = target.previousElementSibling; + + let index = TaskData.findIndex(task => task.Id == taskId.innerHTML); + TaskData.splice(index,1); + + updateLocal(TaskData); + showTasks(TaskData); + if(tasks.children.length == 0) hideSortBtns(); +} + +const randomNum = () => Math.floor(Math.random()*10000) + +addTaskBtn.addEventListener('click', (e) => { + form.style.display = 'flex'; + focusDiv.style.display = 'block'; +}) + +form.addEventListener('submit', (e) => { + e.preventDefault(); + + const taskTitle = form.title.value; + const taskDesc = form.description.value; + + if(!taskTitle || !taskDesc){ + return alert('Text fields are empty') + }; + + TaskData.push({ + 'Id':randomNum(), + 'Task': taskTitle, + 'Description':taskDesc, + 'complete':false, + 'date':Date.now(), + }); + + form.style.display = 'none'; + focusDiv.style.display = 'none'; + + showTasks(TaskData); + updateLocal(TaskData); + showSortBtns(); +}); + +const toggleComplete = (e) => { + let checkbox = e.target; + let task = checkbox.parentElement; + let taskId = task.nextElementSibling.innerHTML; + let checked = checkbox.checked; + + const index = TaskData.findIndex(task => task.Id == taskId); + + checked ? + TaskData[index].complete = true + : TaskData[index].complete = false; + + updateLocal(TaskData); +} + +hideCompleteBtn.onclick = function(e){ + let dataCopy = TaskData.slice(); + dataCopy = dataCopy.filter(task => !task.complete); + showTasks(dataCopy); + if(tasks.children.length == 0) hideSortBtns(); +} + +deleteCompleteBtn.onclick = function(e){ + TaskData = TaskData.filter(task => !task.complete) + showTasks(TaskData) + updateLocal(TaskData); + if(tasks.children.length == 0) hideSortBtns(); +} +showAllBtn.onclick = function(e){ + showTasks(TaskData); + if(tasks.children.length == 0) return hideSortBtns(); + showSortBtns(); +} + +function showSortBtns(){ + sortNameBtn.style.display = 'block'; + sortDateBtn.style.display = 'block'; +} +function hideSortBtns(){ + sortNameBtn.style.display = 'none'; + sortDateBtn.style.display = 'none'; +} + +sortNameBtn.onclick = function(e){ + TaskData.sort((a, b) => { + let at = a.Task.toLowerCase(); + let bt = b.Task.toLowerCase(); + + if(at < bt) return -1; + if(at > bt) return 1; + return 0; + }); + showTasks(TaskData); + updateLocal(TaskData); +} +sortDateBtn.onclick= function(e){ + TaskData.sort((a, b) => { + return a.date - b.date; + }); + showTasks(TaskData); + updateLocal(TaskData); +} \ No newline at end of file diff --git a/style.css b/style.css index e69de29..f4fdd8d 100644 --- a/style.css +++ b/style.css @@ -0,0 +1,177 @@ +body{ + font-family: Arial, Helvetica, sans-serif; + margin:0; + padding:0; +} +.header { + display: flex; + width:100%; + height:75px; + align-items: center; + justify-content:space-between; + box-shadow:0px 0px 10px 5px lightgrey; +} +h1{ + margin:0 0 0 100px; + display: inline-block; + max-height: 37px; + resize: none; +} +#addTaskBtn{ + margin:0 100px 0; + height:35px; + width:110px; + border-radius: 5px; + border:none; + background:lightgrey; + font-size: 15px; + font-weight:bold; +} +#addTaskBtn:hover{ + cursor:pointer; + opacity: 0.75; +} +h2{ + text-align: center; +text-decoration: underline ; +} +#tasks{ + display:grid; + grid-template-columns: repeat(3,1fr); + grid-template-rows: repeat(3, 1fr); + justify-items: center; + width:700px; + margin:auto; +} +.addTaskForm{ + position:absolute; + width:250px; + height:300px; + margin-left:45%; + margin-right:55%; + background-color: white; + border:2px solid black; + border-radius: 5px; + flex-direction: column; + align-items: center; + justify-content: space-evenly; + z-index: 10; +} +.focusDiv{ + position:absolute; + width:100%; + height:100%; + background:grey ; + opacity: 0.7; + z-index: 5; +} +.taskBoilerplate{ + margin:5px; + width:200px; + height:225px; + padding-left:10px; + box-shadow: 0px 0px 10px 5px lightgrey; + border-radius: 15px; + flex-direction:column; + align-items:flex-start; +} +.taskBoilerplate h4{ + margin:20px 0 0 0; +} +.taskBoilerplate p{ + margin-bottom:50px; +} +.taskBoilerplate div{ + display: flex; + margin-top: 50px; +} +.taskBoilerplate input[type=button]{ + position:absolute; + margin:15px 0 170px 150px; +} +.hoverButton{ + position: absolute; + height:75px; + width:75px; + background:lightgrey ; + text-align: center; + border-radius: 100%; + line-height: 650%; + font-weight: bold; + margin-left: auto; + margin-right: auto; + top:-40px; + left:0; + right:0; + cursor:pointer; +} +.menu{ + position: absolute; + display: flex; + height:60px; + width:620px; + align-items: center; + justify-content: space-around; + border-radius: 5px; + background:white ; + margin:auto; + top:-140px; + left:0; + right:0; + z-index:2; +} +.menu input{ + height:30px; + width:175px; + background: lightgrey; + border-radius: 10px; + border:none; + font-size: 14px; + font-weight:500; + cursor:pointer; + +} +.hideMenu{ + position:absolute; + height:25px; + width:45px; + background:lightgrey; + line-height: 150%; + border-radius: 3px; + font-weight:450; + text-align: center; + margin:auto; + top:45px; + left:0; + right:0; + z-index: 3; + cursor:pointer; +} +.sortByName{ + position:absolute; + height:25px; + width:150px; + background:lightgrey; + border-radius: 10px; + text-align: center; + line-height: 150%; + font-weight: 450; + margin:0 0 0 175px; + left:0; + right:0; + cursor: pointer; +} +.sortByDate{ + position:absolute; + height:25px; + width:150px; + background:lightgrey; + border-radius: 10px; + text-align: center; + line-height: 150%; + font-weight: 450; + margin:30px 0 0 175px; + left:0; + right:0; + cursor: pointer; +} \ No newline at end of file