From 83a5bf661255acf18aaed108ef9ae775de80a5eb Mon Sep 17 00:00:00 2001 From: stevennoble78 Date: Wed, 11 Nov 2015 22:36:43 -0800 Subject: [PATCH 1/3] routes created and html page rendered --- .gitignore | 1 + package.json | 26 ++++++++++ public/index.html | 72 ++++++++++++++++++++++++++++ public/main.css | 3 ++ public/main.js | 118 ++++++++++++++++++++++++++++++++++++++++++++++ server.js | 104 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 324 insertions(+) create mode 100644 .gitignore create mode 100644 package.json create mode 100644 public/index.html create mode 100644 public/main.css create mode 100644 public/main.js create mode 100644 server.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40b878d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..1070c96 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "todo-api", + "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" + }, + "author": "", + "license": "ISC", + "dependencies": { + "body-parser": "^1.14.1", + "express": "^4.13.3", + "hbs": "^4.0.0" + }, + "devDependencies": {}, + "repository": { + "type": "git", + "url": "git+https://github.com/stevennoble78/express-todo-app.git" + }, + "bugs": { + "url": "https://github.com/stevennoble78/express-todo-app/issues" + }, + "homepage": "https://github.com/stevennoble78/express-todo-app#readme" +} diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..eac216f --- /dev/null +++ b/public/index.html @@ -0,0 +1,72 @@ + + + + + + + + + + + To Do List + + +
+
+
+

To Do List

+
+
+
+ + + +
+
+
+
+
+

Task

+
+
+

Description

+
+
+ +
+
+
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/public/main.css b/public/main.css new file mode 100644 index 0000000..9863a7f --- /dev/null +++ b/public/main.css @@ -0,0 +1,3 @@ +.editTodo { + display: none; +} \ No newline at end of file diff --git a/public/main.js b/public/main.js new file mode 100644 index 0000000..7c8913e --- /dev/null +++ b/public/main.js @@ -0,0 +1,118 @@ +// wait for DOM to load before running JS +$(document).ready (function () { + + // check to make sure JS is loaded + console.log('JS is loaded!'); + + // Compile the template + var source = $('#template').html(); + var template = Handlebars.compile(source); + var todoResults = []; + var baseUrl = '/'; + var apiUrl = baseUrl + 'api/todos/'; + var $todolist = $('#todo-list'); + var $newTodo = $('#newTodo'); + + // Handlebars list helper + Handlebars.registerHelper('list', function(context, options) { + var ret = ""; + }); + + // Use AJAX to get data and append it to the page + $.get(apiUrl, function(data) { + console.log(data); + todoResults = data; + + // Render the data + var todoHTML = template({todos: todoResults}); + $todolist.append(todoHTML); + }); + + // Refresh function + function refresh (data) { + console.log('refreshing'); + $todolist.empty(); + $('input').val(''); + // Rerender the data + var todoHTML = template({todos: todoResults}); + $todolist.append(todoHTML); + } + + // Add todo function called by submit button handler + function addTodo(data) { + todoResults.push(data); + refresh(); + } + + // Put todo function called by glyphicon pencil handler + function putTodo() { + event.preventDefault(); + var id = $(this).attr('id'); + $('#form' + id).toggle(); + $('#form' + id).on('submit', function(event) { + event.preventDefault(); + var updatedTodo = $(this).serialize(); + $.ajax({ + type: 'PUT', + url: apiUrl + id, + data: updatedTodo, + success: function (data) { + // Get the object to update + var todoToUpdate = todos.filter(function(todo) { + return (todo._id === id); + })[0]; + // Remove the object and replace it with the updated object + todoResults.splice(todoResults.indexOf(todoToUpdate), 1, data); + // var index; + // for (var i=0; i 0) { + newTodo._id = todos[todos.length - 1]._id + 1; + } else { + newTodo._id = 1; + } + // Add new todo to the todos array + todos.push(newTodo); + // Send new todo as JSON resonse + res.json(newTodo); +}); + +// Set up route for updates +app.put('/api/todos/:id', function(req, res) { + // Get todo id from url params + var todoId = parseInt(req.params.id); + // Find todo to update by its id + var todoToUpdate = todos.filter(function(todo) { + return (todo._id === todoId); + })[0]; + // Update the todo's task + req.body._id = todoId; + todos.splice(todos.indexOf(todoToUpdate), 1, req.body); + // We could update the task and the description as well + // Send back JSON data + res.json(req.body); +}); + +// Set up route for deletes +app.delete('/api/todos/:id', function(req, res) { + // Get todo id from url params + var todoId = parseInt(req.params.id); + // Find todo to update by its id + var todoToDelete = todos.filter(function(todo) { + return (todo._id === todoId); + })[0]; + // Delete the todo's task + todos.splice(todos.indexOf(todoToDelete), 1); + // Send back JSON data + res.json(todoToDelete); +}); + +var server = app.listen(process.env.PORT || 5000, function() { + console.log('listening...'); +}); \ No newline at end of file From c0611e8bd9aaddd330bdbc306e14476e9597764e Mon Sep 17 00:00:00 2001 From: stevennoble78 Date: Thu, 12 Nov 2015 09:02:38 -0800 Subject: [PATCH 2/3] routes created and html page rendered --- public/index.html | 1 + server.js | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index eac216f..e8c5a13 100644 --- a/public/index.html +++ b/public/index.html @@ -43,6 +43,7 @@

{{description}}

+
diff --git a/server.js b/server.js index 54b4d9d..a09b72f 100644 --- a/server.js +++ b/server.js @@ -16,19 +16,23 @@ app.use(bodyParser.urlencoded({ extended: true })); var todos = [{ _id: 1, task: 'wake up', - description: 'get up at 7:00am' + description: 'get up at 7:00am', + done: false },{ _id: 2, task: 'make breakfast', - description: 'cook some eggs and toast' + description: 'cook some eggs and toast', + done: false },{ _id: 3, task: 'eat breakfast', - description: 'eat it' + description: 'eat it', + done: false },{ _id: 4, task: 'clean up', - description: 'wash dishes' + description: 'wash dishes', + done: false }]; // Set up route for index.html From fba71fcf6baea18141e0e94111bd7c34148649f0 Mon Sep 17 00:00:00 2001 From: stevennoble78 Date: Fri, 13 Nov 2015 08:40:49 -0800 Subject: [PATCH 3/3] up and running --- .DS_Store | Bin 0 -> 6148 bytes models/.DS_Store | Bin 0 -> 6148 bytes models/todo.js | 15 ++++ package.json | 3 +- public/.DS_Store | Bin 0 -> 6148 bytes public/main.css | 9 +++ public/main.js | 75 ++++++++--------- server.js | 116 +++++++++++---------------- public/index.html => views/index.hbs | 35 ++++---- 9 files changed, 130 insertions(+), 123 deletions(-) create mode 100644 .DS_Store create mode 100644 models/.DS_Store create mode 100644 models/todo.js create mode 100644 public/.DS_Store rename public/index.html => views/index.hbs (64%) diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..565d866cd5d7df9310537238e11f05de69d6f0a5 GIT binary patch literal 6148 zcmeHKF-`+P3>-s1k!VsZUly0Bm{e9)JaaInxpEzD&dSJtuLM%r(*Cj2?&Xu2e7Wqclh^cKTbLW> qDX0xOmuSVrXvO^Dt@!>-SNxg#HF0bh<>aHBs6PVki$V_kh65jw#2`Na literal 0 HcmV?d00001 diff --git a/models/.DS_Store b/models/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0" + options.fn(context[i]) + ""; - } - return ret + ""; - }); + // Set variables + var todoResults = [], + baseUrl = '/', + apiUrl = baseUrl + 'api/todos/', + $todolist = $('#todo-list'), + $newTodo = $('#newTodo'); // Use AJAX to get data and append it to the page $.get(apiUrl, function(data) { - console.log(data); - todoResults = data; + console.log(data.todos); + todoResults = data.todos; // Render the data var todoHTML = template({todos: todoResults}); @@ -36,7 +29,7 @@ $(document).ready (function () { function refresh (data) { console.log('refreshing'); $todolist.empty(); - $('input').val(''); + $('input.formdata').val(''); // Rerender the data var todoHTML = template({todos: todoResults}); $todolist.append(todoHTML); @@ -44,8 +37,12 @@ $(document).ready (function () { // Add todo function called by submit button handler function addTodo(data) { - todoResults.push(data); - refresh(); + event.preventDefault(); + var newTodo = $(this).serialize(); + $.post(apiUrl, newTodo, function(data) { + todoResults.push(data); + refresh(); + }); } // Put todo function called by glyphicon pencil handler @@ -61,20 +58,13 @@ $(document).ready (function () { url: apiUrl + id, data: updatedTodo, success: function (data) { - // Get the object to update - var todoToUpdate = todos.filter(function(todo) { - return (todo._id === id); - })[0]; - // Remove the object and replace it with the updated object - todoResults.splice(todoResults.indexOf(todoToUpdate), 1, data); - // var index; - // for (var i=0; i 0) { - newTodo._id = todos[todos.length - 1]._id + 1; - } else { - newTodo._id = 1; - } - // Add new todo to the todos array - todos.push(newTodo); - // Send new todo as JSON resonse - res.json(newTodo); + // Create a new todo using form data + var newTodo = new Todo(req.body); + + // Save new Todo in db + newTodo.save(function(err, savedTodo) { + res.json(savedTodo); + }); + }); // Set up route for updates app.put('/api/todos/:id', function(req, res) { - // Get todo id from url params - var todoId = parseInt(req.params.id); - // Find todo to update by its id - var todoToUpdate = todos.filter(function(todo) { - return (todo._id === todoId); - })[0]; - // Update the todo's task - req.body._id = todoId; - todos.splice(todos.indexOf(todoToUpdate), 1, req.body); - // We could update the task and the description as well - // Send back JSON data - res.json(req.body); + // Find url from id parameters + var todoId = req.params.id; // Doesn't need to be converted to an integer + + // Find todo in db by id + Todo.findOne({ _id: todoId }, function(err, foundTodo) { + // Update the todo's attributes + foundTodo.task = req.body.task; + foundTodo.description = req.body.description; + + // Save updated todo + foundTodo.save(function(err, savedTodo) { + res.json(foundTodo); + }); + }); }); // Set up route for deletes app.delete('/api/todos/:id', function(req, res) { - // Get todo id from url params - var todoId = parseInt(req.params.id); - // Find todo to update by its id - var todoToDelete = todos.filter(function(todo) { - return (todo._id === todoId); - })[0]; - // Delete the todo's task - todos.splice(todos.indexOf(todoToDelete), 1); - // Send back JSON data - res.json(todoToDelete); + // Find url from id parameters + var todoId = req.params.id; // Doesn't need to be converted to an integer + + // Find todo in db by id + Todo.findOneAndRemove({ _id: todoId }, function(err, deletedTodo) { + res.json(deletedTodo); + }); }); var server = app.listen(process.env.PORT || 5000, function() { diff --git a/public/index.html b/views/index.hbs similarity index 64% rename from public/index.html rename to views/index.hbs index e8c5a13..bc5bfde 100644 --- a/public/index.html +++ b/views/index.hbs @@ -13,14 +13,14 @@
-
+

To Do List


- - - + + +
@@ -33,28 +33,33 @@

Description