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
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// This file contains settings set for the project workspace
{
// Sets the font size in the code editor to 42px
"editor.fontSize": 42,
// Set the font size in the terminal to 62px
"terminal.integrated.fontSize": 62
}
62 changes: 62 additions & 0 deletions index.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<%# This file render the data from server %>
<!DOCTYPE html> <%#Declare this is an HTML5 document%>
<html lang="en"> <%# Opens HTML document, set language to english %>
<head> <%# Opens head section%>
<meta charset="UTF-8"> <%#Sets character encoding to UTF-8 which supports all characters/symbols)%>

<%# Tells Internet Explorer to use the latest rendering engine%>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<%# Makes the page responsive on mobile devices%>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title><%#Sets the browser tab title%>
<%#Links Font Awesome CSS library (for icons like the trash icon)%>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
<%# %>
<link rel="stylesheet" href="css/style.css">
</head><%#Closes head section %>
<body><%# Closes body section %>

<%#line 20 - line 29 are duplicate section %>
<!DOCTYPE html>
<html lang="en">
<head>
<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>Document</title>
</head>
<body>
<h1>Todo List: </h1><%#Set to do list as main heading with h1 size%>
<ul class="todoItems"><%#Use unordered list container for todo items%>
<%#Starts a JS for loop, Loops through the items array %>
<% for(let i=0; i < items.length; i++) {%>
<li class="item"> <%#creates a list item for each todo%>
<%#Checks if current item is marked as completed%>
<% if(items[i].completed === true) {%>
<%#If completed, displays the todo text in a span with 'completed' class%>
<span class='completed'><%= items[i].thing %></span>
<%#If NOT completed, displays the todo text in a regular span (no class)%>
<% }else{
%><span><%= items[i].thing %></span>
<% } %>
<%#Displays a trash can icon for deleting%>
<span class='fa fa-trash'></span>
</li><%#closes the list item%>
<% } %><%#closes the for loop%>
</ul><%#Closes the unordered list%>
<%#Displays count of remaining todos with h2 %>
<h2>Left to do: <%= left %></h2>
<%#Heading for the add todo form%>
<h2>Add A Todo:</h2>

<%#form that submit to /addTodo route with POST method%>
<form action="/addTodo" method="POST">
<%#Text input field for new todo%>
<input type="text" placeholder="Thing To Do" name="todoItem">
<input type="submit"><%#submit button for the form%>
</form><%#closes the form%>
<%#Links external JavaScript file%>
<script src='js/main.js'></script>
<%#Closes body and html tags%>
</body>
</html>
34 changes: 17 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"name": "rap-name-api",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
{ //Open JSON object
"name": "rap-name-api", //declares project name
"version": "1.0.0", //declares project version
"description": "", //describe what the project is generally
"main": "index.js", //the main file that runs once the package get required
"scripts": { //defines custom commands you can run with npm run
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"ejs": "^3.1.6",
"express": "^4.17.1",
"mongodb": "^3.6.5"
}
}
},//close the scripts section
"author": "",// generally contain author name but empty here
"license": "ISC", //list license type is ISC which is permissive open-source license
"dependencies": { //lists packages the app needs to run
"cors": "^2.8.5", //allows your api to be accessed from different domain
"dotenv": "^8.2.0",//loads environment variable from .env file, to hide sensitive data
"ejs": "^3.1.6",//allow JS to be embed in HTML templates
"express": "^4.17.1", //web app framework to handle rounting, requests, responses
"mongodb": "^3.6.5" //connects app to MongoDB database, used to store and retrieve the to do items
}//closes dependencies section
}//closes the entire JSON object
18 changes: 11 additions & 7 deletions public/css/style.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
h1{
color: red;
}
.completed{
color: gray;
text-decoration: line-through;
}
/* This file is an external stylesheet containing CSS code */

h1{ /* Targets every h1 element */
color: red; /* Set the color of the text to red */
} /* end of style declaration for the h1 selector */


.completed{ /* Targets the .completed class */
color: gray; /* Set the color of the text to gray */
text-decoration: line-through; /* Apply a strikethrough effect to the text */
} /* end of style declaration for the .completed class */
117 changes: 70 additions & 47 deletions public/js/main.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,95 @@
// target the class .fa-trash
const deleteBtn = document.querySelectorAll('.fa-trash')
// target the span elements within the element with the class .item
const item = document.querySelectorAll('.item span')
// target the span with the class .completed within the element with the class .item
const itemCompleted = document.querySelectorAll('.item span.completed')

// for each item in the li that has the trash can icon
Array.from(deleteBtn).forEach((element)=>{
element.addEventListener('click', deleteItem)
})
// attach an event listener for each li item when the trash icon is clicked
element.addEventListener('click', deleteItem) // invoke deleteItem(): delete item
})

// for each item with a class .item
Array.from(item).forEach((element)=>{
// attach an event listener to mark the item as complete
element.addEventListener('click', markComplete)
})

// for each li item with a span of a class .completed
Array.from(itemCompleted).forEach((element)=>{
// attach an event listener to mark the item and uncomplete
element.addEventListener('click', markUnComplete)
})

// this function will be called when the trash icon is clicked
async function deleteItem(){
// grab the item the user clicked on to delete
const itemText = this.parentNode.childNodes[1].innerText
try{
const response = await fetch('deleteItem', {
method: 'delete',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
'itemFromJS': itemText
})
})
const data = await response.json()
console.log(data)
location.reload()
// error handling, in case the item does not exist
try{
// initiate the request and wait until a response is received
const response = await fetch('deleteItem', { // target endpoint
method: 'delete', // http method delete, remove the item
// request header, the body of the data is formatted in json
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ // the request body, property set to stringified JSON object
// create key-value pair
'itemFromJS': itemText // itemText = the text of the item to be deleted
}) // end of JSON object
}) // end of fetch call
const data = await response.json() // store the response
console.log(data) // display the response to the console
location.reload() // refresh the web page

}catch(err){
console.log(err)
}
}
}catch(err){ // end of try, catch the error
console.log(err) // display the error in the console
} // end of catch block
} // end of deleteItem function

async function markComplete(){
// this function will mark the item on the todo list as complete
async function markComplete(){ // declare a function name markComplete
// grab the item from the list to mark as complete
const itemText = this.parentNode.childNodes[1].innerText
try{
try{ // start of the error handling
// store the response from the request from the markComplete endpoint
const response = await fetch('markComplete', {
method: 'put',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
'itemFromJS': itemText
})
})
const data = await response.json()
console.log(data)
location.reload()
method: 'put', // http method put, to update the item
// request header, the body of the data is formatted in json
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ // request body, data converted to json
'itemFromJS': itemText // key-value pair, itemText = text of the li item
}) // end of json object
}) // end of fetch
const data = await response.json() // store the response to data
console.log(data) // display the data in console
location.reload() // refresh page

}catch(err){
console.log(err)
}
}
}catch(err){ // catch error, if occured
console.log(err) // display error in console
} // end of catch
} // end of markComplete()

async function markUnComplete(){
// this function changes the item status to incomplete
async function markUnComplete(){
// grabs the text of the item the user clicked on
const itemText = this.parentNode.childNodes[1].innerText
try{
const response = await fetch('markUnComplete', {
method: 'put',
try{ // error handling
// start a fetch request for the endpoint markUnComplete
const response = await fetch('markUnComplete', {
method: 'put', // http method put, updates the status of the item
// request header, the body of the data is formatted in json
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
'itemFromJS': itemText
})
})
const data = await response.json()
console.log(data)
location.reload()
body: JSON.stringify({ // request body, data converted to json
'itemFromJS': itemText // key-value pair, itemText = text of the li item
}) // end of json object
}) // end of fetch request
const data = await response.json() // store response to json in a data variable
console.log(data) // display the data in console
location.reload() // refresh page

}catch(err){
console.log(err)
}
}
}catch(err){ // handle error, if any
console.log(err) // display the error in console
} // end of catch block
} // end of markUnComplete function
Loading