Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mongo version todo app #17

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
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
13 changes: 13 additions & 0 deletions models/todo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

//this tells mongoose what kind of data can be accepted
var TodoSchema = new Schema ({
task: {type: String, minlength: 2},
description: {type: String, minlength: 2}
});

//this sets up the model(object) in Mongo, lets up query db
var Todo = mongoose.model('Todo', TodoSchema);

module.exports = Todo;
25 changes: 25 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"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",
"start": "node server.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/mrockway/express-todo-app.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/mrockway/express-todo-app/issues"
},
"homepage": "https://github.com/mrockway/express-todo-app#readme",
"dependencies": {
"body-parser": "^1.14.1",
"express": "^4.13.3",
"hbs": "^4.0.0"
}
}
Binary file added public/.DS_Store
Binary file not shown.
Binary file added public/legalPad.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 94 additions & 0 deletions public/scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
$(function() {

console.log("10-4 little buddy");

//set up variable for data
// handlebars template and source

var source = $('#task-template').html();
var template = Handlebars.compile(source);

var allTasks = [];

$('.todoList').on('click', '.edit', function(event){
$('.todoEdit').toggle("fast");
});

//refresh book list on page
var render = function() {
$('.todoList').empty();
var todoHtml = template({data : allTasks});
$('.todoList').append(todoHtml);
};

//get request, put todos on the page
$.get('/api/todos/', function(data) {
todoResults = template({data : data.todos});
allTasks = (data.todos);
$('.todoList').append(todoResults);
$('.todoEdit').hide();
return todoResults;
});

//create new todo task
$('.todoForm').on('submit',function(event) {
event.preventDefault();
var newTask = $(this).serialize();
$.post('/api/todos/',newTask, function(data) {
allTasks.push(data);
render();
});
});

//drop down edit form
$('.todoList').on('click','.edit', function(event){
$('.todoEdit').show();
});

//update todo list
$('.todoList').on('submit', '.todoEdit', function(event){
event.preventDefault();
var editTask = $(this).serialize();
var taskId = $(this).closest('.task').attr('data-id');
var taskUpdate = allTasks.filter(function(task) {
return (allTasks._id == taskId);
})[0];
$.ajax({
type: 'PUT',
url: '/api/todos/'+taskId,
data: editTask,
success: function(data){
allTasks.splice(allTasks.indexOf(taskUpdate), 1, data);
render();
}
});
});

//delete todo list items
$('.todoList').on('click', '.delete', function(event){
event.preventDefault();
var taskId = $(this).closest('.task').attr('data-id');
var taskRemove = allTasks.filter(function(task) {
return allTasks._id == taskId;
})[0];
$.ajax({
type: 'DELETE',
url: '/api/todos/'+taskId,
success: function(data){
allTasks.splice(allTasks.indexOf(taskRemove), 1);
render();
}
});
});

}); // end of doc ready










41 changes: 41 additions & 0 deletions public/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
body {
background-image: url("legalpad.jpg");
background-size: 100%;
font-family: 'Handlee', cursive;
}
#line {
color: #101010;
}
button {
margin: 10px 5px 0 0;
text-align: right;
}
.glyphicon {
top: 4px;
}
.todoHeader {
color: #D9534F;
font-size: 50px;
top: 29px;
position: relative;
}
.todoForm {
width: 100%;
border-radius: 5px;
}
.task {
background-color: rgba(204, 204, 204, 0.52);
border-radius: 15px;
margin-bottom: 20px;
}
.todoText {
font-size: 35px;
}
.todoDescription {
font-size: 20px;
}
.todoEdit {
font-size: 15px;
margin-bottom: 15px;
width: 100%;
}
112 changes: 112 additions & 0 deletions server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//require node packages
var express = require('express');
var bodyParser = require('body-parser');
var hbs = require('hbs');
var mongoose = require('mongoose');

//connect to mongoose db
mongoose.connect('mongodb://localhost/tododb');

//require Todo model from the todo.js file
var Todo = require('./models/todo');

//set variable for express function
var app = express();

//set up bodyParser to extract info from URL
app.use(bodyParser.urlencoded({extended: true}));

//set up public folder for css and js
app.use(express.static(__dirname + '/public'));

//set up view engine for hbs if server side render
app.set('view engine', 'hbs');

//route for the index page, prior to setting up index.hbs
app.get('/', function(req,res) {
res.render('index');
});

///////////////////////////
/// MONGO API ROUTES ///
/////////////////////////



////////////////////////////
// mongo find all todos ///
//////////////////////////
app.get('/api/todos', function(req,res) {
Todo.find(function (err, allTodos) {
res.json({todos: allTodos});
});
});

////////////////////////////////
// mongo find one todo item ///
//////////////////////////////
app.get('/api/todos/:id', function(req,res) {
var todoId = req.params.id;
Todo.findOne({_id: todoId}, function(err, foundTodo){
res.json(foundTodo);
});
});


/////////////////////////////
// mongo create new task //
///////////////////////////

app.post('/api/todos', function(req,res) {
var newTodo = new Todo(req.body);
newTodo.save(function(err, savedTodo) {
console.error(err);
res.json(savedTodo);
});
});

app.put('/api/todos/:id', function(req,res) {
var todoId = req.params.id;

Todo.findOne({_id: todoId}, function (err, foundTodo) {
foundTodo.task = req.body.task;
foundTodo.description = req.body.description;
foundTodo.save(function (err, savedTodo) {
res.json(err);
res.json(savedTodo);
});
});
});

////////////////////////////
/// update mongo route ///
//////////////////////////

app.delete('/api/todos/:id', function(req,res){
var todoId = (req.params.id);
Todo.findOneAndRemove({_id: todoId}, function(err, deletedTodo){
res.json(deletedTodo);
});
});

///////////////////////////
// mongo delete route //
//////////////////////////

app.delete('/api/todos/:id', function(req,res){
var todoId = parseInt(req.params.id);
var todoDelete = todos.filter(function(todo) {
return todo._id === todoId;
})[0];
//variable to keep index of todo to be deleted
var todoIndex = todos.indexOf(todoDelete);
//remove todo from array
todos.splice(todoIndex,1);
//send confirmation to user of deletion
return res.json(todoDelete);
});

//telling server to listen to port 3000
app.listen(3000, function() {
console.log("Ready");
});
55 changes: 55 additions & 0 deletions views/index.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ToDo List</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!-- custom css -->
<link rel="stylesheet" href="styles.css">
<link href='https://fonts.googleapis.com/css?family=Handlee' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="text-center todoHeader">to-do list</h1>
<hr>
<h2>add to your list:</h2>
<form class="todoForm input-group">
<input class="form-control" type="text" placeholder="Task" name="task">
<input class="form-control" type="text" placeholder="Description" name="description">
<input class="form-control" type="submit">
</form>
<hr id="line">
</div> <!-- end of to-do header -->
</div> <!-- end of header row -->
<!-- begining of handlebars -->
<div class="todoList row">
<script id="task-template" type="text/x-handlebars-template">
\{{#each data}}
<div class="col-md-8 col-md-offset-2 task" data-id=\{{_id}}>
<button class="edit pull-right"><span class="glyphicon glyphicon-pencil"></span></button>
<button class="delete pull-right"><span class="glyphicon glyphicon-trash"></span></button>
<p class="todoText">\{{task}}</p>
<p class="todoDescription"> - \{{description}}</p>
<form class="todoEdit input-group">
<input class="form-control" type="text" placeholder="EditTask" name="task">
<input class="form-control" type="text" placeholder="Edit Description" name="description">
<input class="form-control" type="submit">
</form>
</div>
<hr>
\{{/each}}
</script>
</div>
</div> <!-- end of container row -->

<!-- handlebars js -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.3/handlebars.min.js"></script>
<!-- jquery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<!-- custom js -->
<script type="text/javascript" src="scripts.js"></script>
</body>
</html>