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
Binary file added .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
15 changes: 15 additions & 0 deletions models/todo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//require mongoose again to use it
var mongoose = require("mongoose"),
Schema = mongoose.Schema;
//schema -- what keys and and datatypes
//
var TodoSchema = new Schema ({
task: {type: String, required: true},
description: {type: String, required: true}
});

//first arguement is name of model, then pass in the schema which is pretty much a constructor
var Todo = mongoose.model("Todo", TodoSchema)

//by exporting the module, we can use the model in another file
module.exports = Todo;
28 changes: 28 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "express-todo-app",
"version": "1.0.0",
"description": "**Objective:** Use Express to make a RESTful API for a to do list. Build a client for your app that uses AJAX and Handlebars templating to `CREATE`, `READ`, `UPDATE`, and `DELETE` todos.",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/alanlee35/express-todo-app.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/alanlee35/express-todo-app/issues"
},
"homepage": "https://github.com/alanlee35/express-todo-app#readme",
"dependencies": {
"body-parser": "^1.14.1",
"chai": "^3.4.1",
"express": "^4.13.3",
"hbs": "^4.0.0",
"mocha": "^2.3.3",
"mongoose": "^4.2.5",
"request": "^2.65.0"
}
}
Binary file added public/.DS_Store
Binary file not shown.
86 changes: 86 additions & 0 deletions public/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
$(function () {
console.log("jsready");

//setting up urls
var urlForJson = "http://localhost:3000/api/todos";
//setting up form variables
var $submitTask = $("#submit_task");
var taskCollection = [];
var $taskList = $("#taskList");
//template for handlebars
var source = $("#todo_template").html();
var template = Handlebars.compile(source);

//create tasks
var createTask = function () {
$taskList.empty();
var taskHtml = template({tasks: taskCollection});
$(taskList).append(taskHtml);
};

//get the json and display it in the index hbs
$.get(urlForJson, function (data) {
console.log(data.todos)
taskCollection = data.todos;
createTask();
}
);
//submit new task, use on click event

$submitTask.on("submit", function (event) {
event.preventDefault();
var newTask = $("#submit_task").serialize();
//post request to add new app
//.post(url, data--specifies data to send to the server along with request,function(data))
//the data param needed to send the task/description to server. function(data) was only setting the id.
$.post(urlForJson, newTask, function (data) {
taskCollection.push(data);
console.log(data)
createTask();
});
$submitTask.trigger("reset");

});

$("body").on("click", ".delete_task", function (data) {
event.preventDefault();
// console.log("clicked");
var taskId = $(this).attr("id");
// console.log(taskId);
var deleteThis = taskCollection.filter(function (todo) {
return todo._id == taskId;
})[0];
$.ajax({
type: "DELETE",
url: urlForJson + "/" + taskId,
success: function (data) {
console.log(data._id)
taskCollection.splice(taskCollection.indexOf(deleteThis), 1);
createTask();
}
})
});
//prevent the edit button from doing anything
$("body").on("click", ".edit_task", function (event) {
event.preventDefault();
});
//updating the task
$("body").on("submit", ".update_todo", function (event) {
event.preventDefault();
var editTaskId = $(this).attr("id");
var updateThis = taskCollection.filter(function (todo) {
return todo._id == editTaskId;
})[0];
//get data from form
var updatedTasks = $(this).serialize();
$.ajax({
type: "PUT",
url: urlForJson + "/" + editTaskId,
data: updatedTasks,
success: function (data) {
taskCollection.splice(taskCollection.indexOf(updateThis), 1, data);
createTask();
}
})
});
});
Binary file added public/paper.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions public/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
body {
font-family: 'Josefin Sans', sans-serif;
background-color: #ECE63D;
}
/*input[type=text] {
background-color: #ECE63D;
}*/

.form-control {
width: 25%;
}

hr {
width: 22%;
color: black;
}

.edi_del {
margin: 0 5px 10px 10px;
padding: 0 10px 0 10px;
}
.bottom {
border-bottom: 2px solid black;
}

p {
font-size: 20px;
margin: 10px 0 0 0;
}
strong {
font-size: 25px;
}
101 changes: 101 additions & 0 deletions server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
var express = require("express");
var app = express();
// require mongoose
var mongoose = require("mongoose");

//http connection
mongoose.connect("mongodb://localhost/todos-app");
//require the Todo model
var Todo = require("./models/todo")

var bodyParser = require("body-parser");
//use the body-parser
app.use(bodyParser.urlencoded({ extended: true }));
//use everything in public folder
app.use(express.static("public"));
var hbs = require("hbs");
//setting hbs view engine
app.set("view engine", "hbs");
//hbs helper
hbs.registerHelper("list", function(context, options) {
var ret = "<ul>";

for(var i=0, j=context.length; i<j; i++) {
ret = ret + "<li>" + options.fn(context[i]) + "</li>";
}

return ret + "</ul>";
});


//route for root
app.get("/", function (req, res) {
res.render("index");
})


//route to get todos as json
app.get("/api/todos", function (req, res) {
// res.json(toDos);
//mongo find all todos in db
Todo.find(function (err, allTodos) {
res.json({todos: allTodos});
});
});

//post server route
app.post("/api/todos", function (req, res) {

// //mongo create new todo with form data ("req.body")
var newTodo = new Todo(req.body);
//save new todo in db
newTodo.save(function (err, savedTodo) {
if(err) {
res.send({error: "Please enter a task"})
}else{

res.json(savedTodo);
};
});
});
//get request for single
app.get("/api/todos/:id", function (req, res) {
//mongo get todo id from url params
var todoId = req.params.id;
//find todo id in db by id
Todo.findOne({_id: todoId}, function (err, foundTodo) {
res.json(foundTodo);
});
});

//route for update
app.put("/api/todos/:id", function (req, res) {
//mongo get id from url params
var todoId = req.params.id;
Todo.findOne({_id: todoId}, function (err, foundTodo) {
//update the attributes
foundTodo.task = req.body.task;
foundTodo.description = req.body.description;
//save updated todo to db
foundTodo.save(function (err, savedTodo) {
res.json(savedTodo);
});
});
});

//route for delete
app.delete("/api/todos/:id", function (req, res) {

var todoId = req.params.id
//find certain id and remove it
Todo.findOneAndRemove({_id: todoId}, function (err, deleteTodo) {
res.json(deleteTodo);
});
});

//setup port
var server = app.listen(process.env.PORT || 3000, function() {
console.log("Listening");
});


72 changes: 72 additions & 0 deletions views/index.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link type="text/css" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link href="https://fonts.googleapis.com/css?family=Josefin+Sans:300italic" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="styles.css">
<meta charset="UTF-8">
<title>Things to do</title>
</head>
<body>
<div class="container">
<h1><u>Things to do</u></h1>
<br>
<form id="submit_task">
<div class="form-group">
<input type="text" class="form-control" name="task" placeholder="Enter new task" required>
</div>
<div class="form-group">
<input type="text" class="form-control" name="description" placeholder="Description">
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary form-control" value="Submit Task">
</div>
</form>

<div id="taskList">
<script type="text/x-handlebars-template" id="todo_template">
<div class="todos">
<br>
\{{#each tasks}}
<div class="row">
<div class="col-md-12 bottom" id="hover">
<p><strong>Task:</strong> \{{task}}</p>{{error}}
<p><strong>Description:</strong> \{{description}}</p>

<a href="#" class="btn btn-danger btn-sm delete_task edi_del pull-right" id="\{{_id}}">Delete</a>
<a href="#" class="btn btn-primary btn-sm edit_task edi_del pull-right" id="\{{_id}}" data-toggle="collapse" data-target="#edit_task_\{{_id}}">Show form</a>

<div class="collapse" id="edit_task_\{{_id}}">
<br>
<form class="update_todo" id="\{{_id}}">
<div class="form-group">
<input type="text" class="form-control" name="task" value="\{{task}}">
</div>
<div class="form-group">
<input type="text" class="form-control" name="description" value="\{{description}}">
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary btn-sm form-control" value="Update">
</div>
</form>
</div>

</div>
</div>
\{{/each}}
</div>
</script>
</div>
<div>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js">
</script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">
</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.3/handlebars.min.js">
</script>
<script type="text/javascript" src="main.js">
</script>


</body>
</html>