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
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"editor.fontSize": 42,
"terminal.integrated.fontSize": 62
"editor.fontSize": 17,
"terminal.integrated.fontSize": 17,
}
50 changes: 32 additions & 18 deletions public/js/main.js
Original file line number Diff line number Diff line change
@@ -1,58 +1,72 @@
// this finds every item in html with class '.fa-trash' and assign it to a variable
const deleteBtn = document.querySelectorAll('.fa-trash')
// this finds every item in html with class '.item span' and assign it to a variable
const item = document.querySelectorAll('.item span')
// this finds every item in html with class '.item span.completed' and assign it to a variable
const itemCompleted = document.querySelectorAll('.item span.completed')

//this add an eventlistner to every trash button and fires a function deleteItem
Array.from(deleteBtn).forEach((element)=>{
element.addEventListener('click', deleteItem)
})

//this add an eventlistner to every item and fires a function markComplete
Array.from(item).forEach((element)=>{
element.addEventListener('click', markComplete)
})

//this add an eventlistner to every complatedItem and fires a function markUnComplete
Array.from(itemCompleted).forEach((element)=>{
element.addEventListener('click', markUnComplete)
})

//Async function that fired as someone click the trash can and it get the task text and sends it to the server as /deleteItem route with a method of delete
async function deleteItem(){
//get task text next to the trash icon
const itemText = this.parentNode.childNodes[1].innerText
try{
//Send fetch request to server
const response = await fetch('deleteItem', {
//specifeing what method we using
method: 'delete',
//specifying the Content-Type of the request
headers: {'Content-Type': 'application/json'},
//data we sending
body: JSON.stringify({
'itemFromJS': itemText
})
})
const data = await response.json()
console.log(data)
//refresh after everything went okey
location.reload()

}catch(err){
console.log(err)
}
}

//async function that fired as someone click the task, it get that task text and send it to the server as /markComplete route with a method of put
async function markComplete(){
const itemText = this.parentNode.childNodes[1].innerText
try{
const response = await fetch('markComplete', {
method: 'put',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
'itemFromJS': itemText
//get task text
const itemText = this.parentNode.childNodes[1].innerText
try{
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()

}catch(err){
console.log(err)
const data = await response.json()
console.log(data)
location.reload()
}catch(err){
console.log(err)
}
}
}

//async function that fired as someone click the task, it get that task text and send it to the server as /markUnComplete route with a method of put
async function markUnComplete(){
//get task text
const itemText = this.parentNode.childNodes[1].innerText
try{
const response = await fetch('markUnComplete', {
Expand Down
30 changes: 21 additions & 9 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
const express = require('express')
//creates Express app
const app = express()
//gets MongoClient
const MongoClient = require('mongodb').MongoClient
//port of our server
const PORT = 2121
//this line allows us to use .env
require('dotenv').config()


//mongoDB connection URI
let db,
dbConnectionStr = process.env.DB_STRING,
dbName = 'todo'

//connect us to the DB
MongoClient.connect(dbConnectionStr, { useUnifiedTopology: true })
.then(client => {
console.log(`Connected to ${dbName} Database`)
db = client.db(dbName)
})

//allows us to use .ejs
app.set('view engine', 'ejs')
//allow our server acces to all folders and files in Public folder
app.use(express.static('public'))
//registers Express middleware to parse URL-encoded request bodies
app.use(express.urlencoded({ extended: true }))
//allow use to use json
app.use(express.json())


//this function fires when someone goes to the main page and it goes to todos DB and get all data then send it to the index.ejs as an array
app.get('/',async (request, response)=>{
const todoItems = await db.collection('todos').find().toArray()
//counts how many data have complated false and return it a number
const itemsLeft = await db.collection('todos').countDocuments({completed: false})
response.render('index.ejs', { items: todoItems, left: itemsLeft })
// db.collection('todos').find().toArray()
Expand All @@ -34,16 +42,18 @@ app.get('/',async (request, response)=>{
// })
// .catch(error => console.error(error))
})

//this function fired with a post fetch with rout /addTodo and it add a task from request.body.todoItem text and give it propriety of complated false
app.post('/addTodo', (request, response) => {
db.collection('todos').insertOne({thing: request.body.todoItem, completed: false})
.then(result => {
//logs todo added in terminal
console.log('Todo Added')
//reload page after task added
response.redirect('/')
})
.catch(error => console.error(error))
})

//this function fired with a put fetch with rout /markComplete and it change a task with request.body.itemFromJS complated proriety to true
app.put('/markComplete', (request, response) => {
db.collection('todos').updateOne({thing: request.body.itemFromJS},{
$set: {
Expand All @@ -60,14 +70,16 @@ app.put('/markComplete', (request, response) => {
.catch(error => console.error(error))

})

//this function fired with a put fetch with rout /markUnComplete and it change a task with request.body.itemFromJS complated proriety to false
app.put('/markUnComplete', (request, response) => {
db.collection('todos').updateOne({thing: request.body.itemFromJS},{
$set: {
completed: false
}
},{
//sort tasks from first one added to last
sort: {_id: -1},
//if there is no task with request.body.itemFromJS it doesnt create new one
upsert: false
})
.then(result => {
Expand All @@ -77,7 +89,7 @@ app.put('/markUnComplete', (request, response) => {
.catch(error => console.error(error))

})

//this function fired with a delete fetch with route /deleteItem and it delete the task with request.body.itemFromJS
app.delete('/deleteItem', (request, response) => {
db.collection('todos').deleteOne({thing: request.body.itemFromJS})
.then(result => {
Expand All @@ -87,7 +99,7 @@ app.delete('/deleteItem', (request, response) => {
.catch(error => console.error(error))

})

//making a server
app.listen(process.env.PORT || PORT, ()=>{
console.log(`Server running on port ${PORT}`)
})
17 changes: 12 additions & 5 deletions views/index.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,35 @@
</head>
<body>
<h1>Todo List: </h1>
<!-- // this create a unorder list that our DB data will goes in -->
<ul class="todoItems">
<!--for loop that goes trough every item from DB -->
<% for(let i=0; i < items.length; i++) {%>
<li class="item">
<!-- list that our that data will go in -->
<li class="item">
<!-- condition to check if item is completed if it is it will add a class completed to the span -->
<% if(items[i].completed === true) {%>
<span class='completed'><%= items[i].thing %></span>
<% }else{ %>
<span><%= items[i].thing %></span>
<% } %>
<% } %>
<!--"fa fa-trash" is a name of an icon(trash) -->
<span class='fa fa-trash'></span>
</li>
<% } %>
</ul>

<!-- "<%= left %>" makes the text goes left -->
<h2>Left to do: <%= left %></h2>

<h2>Add A Todo:</h2>

<!-- form that have method of POST that post new data to the DB with a fetch url of /addTodo -->
<form action="/addTodo" method="POST">
<!-- input of data that will be sent and giving it a name attribute that the server will be looking for to receive the text content-->
<input type="text" placeholder="Thing To Do" name="todoItem">
<!-- the button that will sent the form -->
<input type="submit">
</form>


<script src='js/main.js'></script>
</body>
Expand Down