[
  {
    "path": "README.md",
    "content": "# Node.js-Expess-MongoDB-CRUD\n\nContent discussed : \n - Form Design \n - Post Form Data into Node.js\n - Implemented Form Validation with mongoose model\n - Insert, Update and Delete with Node and MongoDB\n\n## Get the Code\n\n```\n$ git clone https://github.com/CodAffection/Node.js-Expess-MongoDB-CRUD.git\n$ cd Node.js-Expess-MongoDB-CRUD/project\n$ npm install\n```\n\n ## How it works ?\n \n :tv: Video tutorial on this same topic  \n Url : https://youtu.be/voDummz1gO0\n \n<a href=\"http://www.youtube.com/watch?feature=player_embedded&v=voDummz1gO0\n\" target=\"_blank\"><img src=\"http://img.youtube.com/vi/voDummz1gO0/0.jpg\" \nalt=\"Video Tutorial for Node.js-Expess-MongoDB-CRUD\" width=\"500\" height=\"400\" border=\"10\" /></a>\n\n\n| :bar_chart:               |  List of Tutorials   |   | :moneybag:           | Support Us                           |\n|--------------------------:|:---------------------|---|---------------------:|:-------------------------------------|\n| Angular                   |http://bit.ly/2KQN9xF |   |Paypal                | https://goo.gl/bPcyXW                |\n| Asp.Net Core              |http://bit.ly/30fPDMg |   |Amazon   Affiliate    | https://geni.us/JDzpE                |\n| React                     |http://bit.ly/325temF |   |\n| Python                    |http://bit.ly/2ws4utg |   | :point_right:        | Follow Us                            |\n| Node.js                   |https://goo.gl/viJcFs |   |Website               |http://www.codaffection.com          |\n| Asp.Net MVC               |https://goo.gl/gvjUJ7 |   |YouTube               |https://www.youtube.com/codaffection  |\n| Flutter                   |https://bit.ly/3ggmmJz|   |Facebook              |https://www.facebook.com/codaffection |\n| Web API                   |https://goo.gl/itVayJ |   |Twitter               |https://twitter.com/CodAffection      |\n| MEAN Stack                |https://goo.gl/YJPPAH |   |\n| C# Tutorial               |https://goo.gl/s1zJxo |   |\n| Asp.Net WebForm           |https://goo.gl/GXC2aJ |   |\n| C# WinForm                |https://goo.gl/vHS9Hd |   |\n| MS SQL                    |https://goo.gl/MLYS9e |   |\n| Crystal Report            |https://goo.gl/5Vou7t |   |\n| CG Exercises in C Program |https://goo.gl/qEWJCs |   |\n\n"
  },
  {
    "path": "project/controllers/employeeController.js",
    "content": "const express = require('express');\nvar router = express.Router();\nconst mongoose = require('mongoose');\nconst Employee = mongoose.model('Employee');\n\nrouter.get('/', (req, res) => {\n    res.render(\"employee/addOrEdit\", {\n        viewTitle: \"Insert Employee\"\n    });\n});\n\nrouter.post('/', (req, res) => {\n    if (req.body._id == '')\n        insertRecord(req, res);\n        else\n        updateRecord(req, res);\n});\n\n\nfunction insertRecord(req, res) {\n    var employee = new Employee();\n    employee.fullName = req.body.fullName;\n    employee.email = req.body.email;\n    employee.mobile = req.body.mobile;\n    employee.city = req.body.city;\n    employee.save((err, doc) => {\n        if (!err)\n            res.redirect('employee/list');\n        else {\n            if (err.name == 'ValidationError') {\n                handleValidationError(err, req.body);\n                res.render(\"employee/addOrEdit\", {\n                    viewTitle: \"Insert Employee\",\n                    employee: req.body\n                });\n            }\n            else\n                console.log('Error during record insertion : ' + err);\n        }\n    });\n}\n\nfunction updateRecord(req, res) {\n    Employee.findOneAndUpdate({ _id: req.body._id }, req.body, { new: true }, (err, doc) => {\n        if (!err) { res.redirect('employee/list'); }\n        else {\n            if (err.name == 'ValidationError') {\n                handleValidationError(err, req.body);\n                res.render(\"employee/addOrEdit\", {\n                    viewTitle: 'Update Employee',\n                    employee: req.body\n                });\n            }\n            else\n                console.log('Error during record update : ' + err);\n        }\n    });\n}\n\n\nrouter.get('/list', (req, res) => {\n    Employee.find((err, docs) => {\n        if (!err) {\n            res.render(\"employee/list\", {\n                list: docs\n            });\n        }\n        else {\n            console.log('Error in retrieving employee list :' + err);\n        }\n    });\n});\n\n\nfunction handleValidationError(err, body) {\n    for (field in err.errors) {\n        switch (err.errors[field].path) {\n            case 'fullName':\n                body['fullNameError'] = err.errors[field].message;\n                break;\n            case 'email':\n                body['emailError'] = err.errors[field].message;\n                break;\n            default:\n                break;\n        }\n    }\n}\n\nrouter.get('/:id', (req, res) => {\n    Employee.findById(req.params.id, (err, doc) => {\n        if (!err) {\n            res.render(\"employee/addOrEdit\", {\n                viewTitle: \"Update Employee\",\n                employee: doc\n            });\n        }\n    });\n});\n\nrouter.get('/delete/:id', (req, res) => {\n    Employee.findByIdAndRemove(req.params.id, (err, doc) => {\n        if (!err) {\n            res.redirect('/employee/list');\n        }\n        else { console.log('Error in employee delete :' + err); }\n    });\n});\n\nmodule.exports = router;"
  },
  {
    "path": "project/models/db.js",
    "content": "const mongoose = require('mongoose');\n\nmongoose.connect('mongodb://localhost:27017/EmployeeDB', { useNewUrlParser: true }, (err) => {\n    if (!err) { console.log('MongoDB Connection Succeeded.') }\n    else { console.log('Error in DB connection : ' + err) }\n});\n\nrequire('./employee.model');"
  },
  {
    "path": "project/models/employee.model.js",
    "content": "const mongoose = require('mongoose');\n\nvar employeeSchema = new mongoose.Schema({\n    fullName: {\n        type: String,\n        required: 'This field is required.'\n    },\n    email: {\n        type: String\n    },\n    mobile: {\n        type: String\n    },\n    city: {\n        type: String\n    }\n});\n\n// Custom validation for email\nemployeeSchema.path('email').validate((val) => {\n    emailRegex = /^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n    return emailRegex.test(val);\n}, 'Invalid e-mail.');\n\nmongoose.model('Employee', employeeSchema);"
  },
  {
    "path": "project/package.json",
    "content": "{\n  \"name\": \"project\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"server.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"body-parser\": \"^1.18.3\",\n    \"express\": \"^4.16.4\",\n    \"express-handlebars\": \"^3.0.0\",\n    \"mongoose\": \"^5.3.4\"\n  }\n}\n"
  },
  {
    "path": "project/server.js",
    "content": "require('./models/db');\n\nconst express = require('express');\nconst path = require('path');\nconst exphbs = require('express-handlebars');\nconst bodyparser = require('body-parser');\n\nconst employeeController = require('./controllers/employeeController');\n\nvar app = express();\napp.use(bodyparser.urlencoded({\n    extended: true\n}));\napp.use(bodyparser.json());\napp.set('views', path.join(__dirname, '/views/'));\napp.engine('hbs', exphbs({ extname: 'hbs', defaultLayout: 'mainLayout', layoutsDir: __dirname + '/views/layouts/' }));\napp.set('view engine', 'hbs');\n\napp.listen(3000, () => {\n    console.log('Express server started at port : 3000');\n});\n\napp.use('/employee', employeeController);"
  },
  {
    "path": "project/views/employee/addOrEdit.hbs",
    "content": "<h3>{{viewTitle}}</h3>\n\n<form action=\"/employee\" method=\"POST\" autocomplete=\"off\">\n    <input type=\"hidden\" name=\"_id\" value=\"{{employee._id}}\">\n    <div class=\"form-group\">\n        <label>Full Name</label>\n        <input type=\"text\" class=\"form-control\" name=\"fullName\" placeholder=\"Full Name\" value=\"{{employee.fullName}}\">\n        <div class=\"text-danger\">\n            {{employee.fullNameError}}</div>\n    </div>\n    <div class=\"form-group\">\n        <label>Email</label>\n        <input type=\"text\" class=\"form-control\" name=\"email\" placeholder=\"Email\" value=\"{{employee.email}}\">\n        <div class=\"text-danger\">\n            {{employee.emailError}}</div>\n    </div>\n    <div class=\"form-row\">\n        <div class=\"form-group col-md-6\">\n            <label>Mobile</label>\n            <input type=\"text\" class=\"form-control\" name=\"mobile\" placeholder=\"Mobile\" value=\"{{employee.mobile}}\">\n        </div>\n        <div class=\"form-group col-md-6\">\n            <label>City</label>\n            <input type=\"text\" class=\"form-control\" name=\"city\" placeholder=\"City\" value=\"{{employee.city}}\">\n        </div>\n    </div>\n    <div class=\"form-group\">\n        <button type=\"submit\" class=\"btn btn-info\"><i class=\"fa fa-database\"></i> Submit</button>\n        <a class=\"btn btn-secondary\" href=\"/employee/list\"><i class=\"fa fa-list-alt\"></i> View All</a>\n    </div>\n</form>"
  },
  {
    "path": "project/views/employee/list.hbs",
    "content": "<h3><a class=\"btn btn-secondary\" href=\"/employee\"><i class=\"fa fa-plus\"></i> Create New</a> Employee List</h3>\n<table class=\"table table-striped\">\n    <thead>\n        <tr>\n            <th>Full Name</th>\n            <th>Email</th>\n            <th>Mobile</th>\n            <th>City</th>\n            <th></th>\n        </tr>\n    </thead>\n    <tbody>\n        {{#each list}}\n        <tr>\n            <td>{{this.fullName}}</td>\n            <td>{{this.email}}</td>\n            <td>{{this.mobile}}</td>\n            <td>{{this.city}}</td>\n            <td>\n                <a href=\"/employee/{{this._id}}\"><i class=\"fa fa-pencil fa-lg\" aria-hidden=\"true\"></i></a>\n                <a href=\"/employee/delete/{{this._id}}\" onclick=\"return confirm('Are you sure to delete this record ?');\"><i class=\"fa fa-trash fa-lg\" aria-hidden=\"true\"></i></a>\n            </td>\n        </tr>\n        {{/each}}\n    </tbody>\n</table>"
  },
  {
    "path": "project/views/layouts/mainLayout.hbs",
    "content": "<!DOCTYPE html>\n\n<html>\n\n<head>\n    <title>Node.js express mongDB CRUD</title>\n    <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css\" integrity=\"sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO\"\n        crossorigin=\"anonymous\">\n    <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css\">\n</head>\n\n<body class=\"bg-info\">\n    <div class=\"row\">\n        <div class=\"col-md-6 offset-md-3\" style=\"background-color: #fff;margin-top: 25px;padding:20px;\">\n            {{{body}}}\n        </div>\n    </div>\n\n</body>\n\n</html>"
  }
]