Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions 1-Vanilla/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="index.js"></script>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vanilla TODO List</title>
</head>
<body class='page-body'>
<div class='header' >
<h1>Vanilla TODO List</h1>
</div>
<div class='main-body'>
<div class='menu'>
<div class='menu-title' >
Edit items and add new items
</div>
<div class='item'>
<div class='menu-item'><span>title: </span><input id='title-input' required class='title-input' type='text'/></div>
<div class='menu-item'><span>content: </span><input id='content-input' class='content-input' type='textarea'/></div>
</div>
<div class='menu-buttons'>
<button id='clear-button' class='clear-button'>clear</button>
<button id='menu-button' class='menu-button'>add item</button>
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

why add is called menu-button?

<button id='cancel-button' class='menu-button' hidden='true'>cancel edit</button>
</div>
</div>
<div class='display'>
<ul id='list' class='todo-list'>
<!-- to be added dynamically-->
</ul>
<button id='add-button' class='add-button'>add new todo item</button>
</div>
</div>
</body>
</html>
172 changes: 172 additions & 0 deletions 1-Vanilla/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
let editedID = 0;
let editMode = false;

function getNewID(){
return Math.floor(Math.random()*1000)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

not good enough. the probability of getting the same id is 1/1000 which is pretty high. why didn't u take the guid generation function?

function uuidv4() {
  return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
    (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  );
}

}
function addItem(){
let title = document.getElementById('title-input').value
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

the default should be always const unless your'e going to change either the pointer or if it's a primitive its value.
change all let to const unless u have to use let

if (title ==''){
alert('cant add an item without a title')
return
}
if (editMode){
alert('cant add an item while in edit mode')
return
}
let content = document.getElementById('content-input').value
let list = document.getElementById('list')
let id = getNewID()
let itemElement = createTodoItemElement(id,title,content)

list.appendChild(itemElement)
// now save to local storage
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

no comments

let itemString = `title: ${title};content: ${content}`
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

line 24+25 should be in its own function

localStorage.setItem(id,itemString)

// reset menu display
clearMenu()
document.getElementById('menu-button').innerText = 'add item'
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

where's the shortcut for document.getElementById(X).value?

}

function sendItemToEdit(itemID){
editedID = itemID
document.getElementById('title-input').value = document.getElementById(`title${itemID}`).innerText
document.getElementById('content-input').value = document.getElementById(`content${itemID}`).innerText
editMode = true //to disable item deletion
document.getElementById('cancel-button').hidden = false // to exit edit mode
document.getElementById('menu-button').innerText = 'add changes' // to save changes and exit edit mode
}

function deleteItem(itemID){
if(editMode){
alert('cant delete while in edit mode')
return
}
let item = document.getElementById(itemID)
let list = document.getElementById('list')
// remove from display
list.removeChild(item)
// remove from item storage
localStorage.removeItem(itemID)
}

function cancelEdit(){
clearMenu()
editMode = false
document.getElementById('menu-button').innerText = 'add item'
document.getElementById('cancel-button').hidden = true
editedID = 0
}

function clearMenu(){
document.getElementById('title-input').value = ''
document.getElementById('content-input').value = ''
}

function menuButtonClick(){
if(!editMode){
addItem()
}else{
if (document.getElementById('title-input').value == ''){
alert('cant set an empty title')
return
}
let title = document.getElementById('title-input').value
let content = document.getElementById('content-input').value
document.getElementById(`title${editedID}`).innerText = title
document.getElementById(`content${editedID}`).innerText = content
// now update item in local storage
let itemObject = `title: ${title};content: ${content}`
localStorage.setItem(editedID,itemObject)

clearMenu()
editMode = false
document.getElementById('menu-button').innerText = 'add item'
document.getElementById('cancel-button').hidden = true
editedID = 0
}
}
function addButton(){
clearMenu()
document.getElementById('title-input').focus()
}
function createTodoItemElement(itemID,title,content){

// ol todo-item
let itemElement = document.createElement('ol')
itemElement.className = 'todo-item'
itemElement.id = itemID;
// input checkbox
let itemCheckboxElement = document.createElement('input')
itemCheckboxElement.type = 'checkbox'
itemCheckboxElement.className = 'item-checkbox'
// div todo-item-text
let itemTextElement = createItemTextElement(itemID,title,content)
let itemButtonsElement = createItemButtonsElement(itemID)
//append checkbox, text and buttons to list-item
itemElement.appendChild(itemCheckboxElement)
itemElement.appendChild(itemTextElement)
itemElement.appendChild(itemButtonsElement)

return itemElement
}
function createItemButtonsElement(itemID){

let itemButtonsElement = document.createElement('div')
itemButtonsElement.className = 'todo-item-buttons'
// button edit
let editButtonElement = document.createElement('button')
editButtonElement.innerText = 'edit'
editButtonElement.className = 'item-edit-button'
editButtonElement.setAttribute('onclick',`sendItemToEdit(${itemID})`)
// button delete
let deleteButtonElement = document.createElement('button')
deleteButtonElement.innerText = 'delete'
deleteButtonElement.className = 'item-delete-button'
deleteButtonElement.setAttribute('onclick',`deleteItem(${itemID})`)
// append the buttons to container
itemButtonsElement.appendChild(editButtonElement)
itemButtonsElement.appendChild(deleteButtonElement)

return itemButtonsElement
}
function createItemTextElement(itemID,title,content){

let itemTextElement = document.createElement('div')
itemTextElement.className = 'todo-item-text'
// item title
let titleElement = document.createElement('div')
titleElement.innerText = title
titleElement.className = 'todo-item-title'
titleElement.id = 'title'+itemID
// item content
let contentElement = document.createElement('div')
contentElement.innerText = content
contentElement.className = 'todo-item-content'
contentElement.id = 'content'+itemID
// append text to parent container
itemTextElement.appendChild(titleElement)
itemTextElement.appendChild(contentElement)

return itemTextElement
}
// attach functions to menu buttons
window.onload = function(){
document.getElementById('clear-button').setAttribute('onclick','clearMenu()')
document.getElementById('menu-button').setAttribute('onclick','menuButtonClick()')
document.getElementById('cancel-button').setAttribute('onclick','cancelEdit()')
document.getElementById('add-button').setAttribute('onclick','addButton()')
// load display todo items from local storage
let list = document.getElementById('list')
for (let key in localStorage) {
if(isNaN(Number(key)))
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

what's that? what failed so u had to add this condition?

continue;
let itemString = localStorage.getItem(key)
itemString = itemString.split(';')
let title = itemString[0].split(':')[1]
let content = itemString[1].split(':')[1]
let itemElement = createTodoItemElement(Number(key),title,content)
list.appendChild(itemElement)
}
}
12 changes: 12 additions & 0 deletions 1-Vanilla/list-item.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<ol class='todo-item'>
<input class='item-checkbox' type='checkbox'/>
<div class='todo-item-text'>
<div class='todo-item-title'>title</div>
<div class='todo-item-subtitle'>sub-title</div>
<div class='todo-item-content'>content</div>
</div>
<div class='todo-item-buttons'>
<button class='item-edit-button'>edit</button>
<button class='item-delete-button'>delete</button>
</div>
</ol>
145 changes: 145 additions & 0 deletions 1-Vanilla/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
button{
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
border: none;
background-color: white;
border-radius: 10px;
height:40px;
margin: 5px
}
button:hover{
transform: scale(1.3)
}
input{
margin: 0px 10px;
}
input:hover{
transform: scale(1.1);
}
.page-body{
display:flex;
flex-direction:column;
height: 100vh;
}
.header{
background-color: lightblue;
padding: 20px 20px 10px 20px;
border-bottom: solid 3px rgb(0, 140, 255);
}
.main-body{
display:flex;
flex-direction:row;
height: 100vh;
}
.menu{
background-color: whitesmoke;
padding: 10px;
border-right: solid 2px grey;
}
.menu-buttons{
display: flex;
justify-content: space-around;
}
.menu-item{
display: flex;
flex-direction: row;
justify-content: end;
margin: 5px;
width: 100%;
}
.content-input{
height:50px;
}
.item{
display:flex;
flex-direction:column;
align-items: end;
}
.display{
min-width: 40%;
max-width: 60%;
display: flex;
flex-direction: column;
margin: 10px;
justify-content: start;
align-items: center;
}
.todo-item{
display: flex;
flex-direction: row;
justify-content: space-between;
padding:5px;
border-radius: 10px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
margin-bottom: 12px;
}

.item-checkbox{
margin-right: 10px;
}
.item-checkbox:checked ~div.todo-item-text > .todo-item-title {
text-decoration: line-through;
}
.item-checkbox:checked ~div.todo-item-text > .todo-item-subtitle {
text-decoration: line-through;
}
.item-checkbox:checked ~div.todo-item-text > .todo-item-content {
display: none;
}
.todo-item-text{
display: flex;
flex-direction: column;
align-self: stretch;
}
.todo-item-buttons{
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.item-edit-button{
font-family: 'Material Icons';
font-size: 30px;
text-align: center;
color: white;
width:40px;
height:40px;
border-radius: 30%;
background-color: greenyellow;
}
.item-edit-button:hover{
background-color: seagreen;
}
.item-delete-button{
font-family: 'Material Icons';
font-size: 30px;
text-align: center;
color: white;
width:40px;
height:40px;
border-radius: 30%;
background-color: tomato;
}
.item-delete-button:hover{
background-color: crimson;
}
.item-checkbox{
align-self: center;
}
.item-checkbox:hover{
transform: scale(1.3);
}
.todo-item-title{
font-size: 20px;
font-weight: bold;
}
.todo-item-subtitle{
font-size: 20px;
color: grey;
font-weight: thin;
padding-left: 15px;
}
.todo-item-content{
font-weight: thin;
padding-left: 15px;
color: grey;
}