diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..5af06d1 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/models/todo.js b/models/todo.js new file mode 100644 index 0000000..f054a5b --- /dev/null +++ b/models/todo.js @@ -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; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..05253ef --- /dev/null +++ b/package.json @@ -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" + } +} diff --git a/public/.DS_Store b/public/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/public/.DS_Store differ diff --git a/public/legalPad.jpg b/public/legalPad.jpg new file mode 100644 index 0000000..e2d89b6 Binary files /dev/null and b/public/legalPad.jpg differ diff --git a/public/scripts.js b/public/scripts.js new file mode 100644 index 0000000..9fd27c1 --- /dev/null +++ b/public/scripts.js @@ -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 + + + + + + + + + + diff --git a/public/styles.css b/public/styles.css new file mode 100644 index 0000000..c13aa6c --- /dev/null +++ b/public/styles.css @@ -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%; +} \ No newline at end of file diff --git a/server.js b/server.js new file mode 100644 index 0000000..95daa77 --- /dev/null +++ b/server.js @@ -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"); +}); \ No newline at end of file diff --git a/views/index.hbs b/views/index.hbs new file mode 100644 index 0000000..888d553 --- /dev/null +++ b/views/index.hbs @@ -0,0 +1,55 @@ + + +
+ +