├── README.md
├── .idea
├── .gitignore
├── modules.xml
└── project.iml
├── models
├── db.js
└── employee.model.js
├── package.json
├── index.js
├── node.txt
├── views
├── layouts
│ └── mainLayout.hbs
└── employee
│ ├── list.hbs
│ └── addOrEdit.hbs
└── controllers
└── employeeController.js
/README.md:
--------------------------------------------------------------------------------
1 | # full-stack-app
2 | NodeJS ExpressJS MongoDB
3 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/models/db.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 |
3 | mongoose.connect('mongodb://localhost:27017/node', { useNewUrlParser: true }, (err) => {
4 | if (!err) {
5 | console.log('Mongo DB connected successfully')
6 | }else{
7 | console.log('Error in db connection: ' + err)
8 | }
9 | })
10 |
11 | require('./employee.model')
--------------------------------------------------------------------------------
/.idea/project.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "body-parser": "^1.18.3",
4 | "express": "^4.16.4",
5 | "express-handlebars": "^3.0.0",
6 | "mongoose": "^5.3.4"
7 | },
8 | "name": "project",
9 | "version": "1.0.0",
10 | "main": "index.js",
11 | "devDependencies": {
12 | "nodemon": "^2.0.7"
13 | },
14 | "scripts": {
15 | "start": "node index.js",
16 | "dev": "nodemon index.js"
17 | },
18 | "keywords": [],
19 | "author": "Samar Badriddinov",
20 | "license": "ISC",
21 | "description": ""
22 | }
23 |
--------------------------------------------------------------------------------
/models/employee.model.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 |
3 | const employeeSchema = new mongoose.Schema({
4 | fullName: {
5 | type: String,
6 | required: 'This field is required'
7 | },
8 | email: {
9 | type: String
10 | },
11 | mobile: {
12 | type: String
13 | },
14 | city: {
15 | type: String
16 | }
17 | })
18 |
19 | // Custom validation for email
20 | employeeSchema.path('email').validate((val) => {
21 | 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,}))$/;
22 | return emailRegex.test(val);
23 | }, 'Invalid e-mail.');
24 |
25 | mongoose.model('Employee', employeeSchema)
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | require('./models/db');
2 |
3 | const express = require('express');
4 | const path = require('path');
5 | const exphbs = require('express-handlebars');
6 | const bodyparser = require('body-parser');
7 |
8 | const employeeController = require('./controllers/employeeController');
9 |
10 | let app = express();
11 | app.use(bodyparser.urlencoded({
12 | extended: true
13 | }));
14 | app.use(bodyparser.json());
15 | app.set('views', path.join(__dirname, '/views/'));
16 | app.engine('hbs', exphbs({ extname: 'hbs', defaultLayout: 'mainLayout', layoutsDir: __dirname + '/views/layouts/' }));
17 | app.set('view engine', 'hbs');
18 |
19 | app.listen(5000, () => {
20 | console.log('Express server started at port : 5000');
21 | });
22 |
23 | app.use('/employee', employeeController);
--------------------------------------------------------------------------------
/node.txt:
--------------------------------------------------------------------------------
1 | npm i --s express@4.16.4 mongoose@5.3.4 express-handlebars@3.0.0 body-parser@1.18.3
2 |
3 | Bootstrap CDN
4 |
5 | Fontawesome CDN
6 |
7 |
8 | Custom validation for email
9 | employeeSchema.path('email').validate((val) => {
10 | 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,}))$/;
11 | return emailRegex.test(val);
12 | }, 'Invalid e-mail.');
13 |
--------------------------------------------------------------------------------
/views/layouts/mainLayout.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 | CRUD
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{{body}}}
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/views/employee/list.hbs:
--------------------------------------------------------------------------------
1 |
2 | Create New
3 | Employee List
4 |
5 |
6 |
7 |
8 |
9 | | Full Name |
10 | Email |
11 | Mobile |
12 | City |
13 | |
14 |
15 |
16 |
17 | {{#each list}}
18 |
19 | | {{this.fullName}} |
20 | {{this.email}} |
21 | {{this.mobile}} |
22 | {{this.city}} |
23 |
24 |
25 |
26 | |
27 |
28 | {{/each}}
29 |
30 |
--------------------------------------------------------------------------------
/views/employee/addOrEdit.hbs:
--------------------------------------------------------------------------------
1 | {{viewTitle}}
2 |
--------------------------------------------------------------------------------
/controllers/employeeController.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const router = express.Router()
3 | const mongoose = require('mongoose')
4 | const Employee = mongoose.model('Employee')
5 |
6 | router.get('/', (req, res) => {
7 | res.render('employee/addOrEdit', {
8 | viewTitle: 'Insert Employee'
9 | })
10 | })
11 |
12 | router.post('/', (req, res) => {
13 | if (req.body._id === ""){
14 | insertRecord(req, res)
15 | }else{
16 | updateRecord(req, res)
17 | }
18 | })
19 |
20 | function insertRecord(req, res) {
21 | let employee = new Employee();
22 | employee.fullName = req.body.fullName
23 | employee.email = req.body.email
24 | employee.mobile = req.body.mobile
25 | employee.city = req.body.city
26 | employee.save((err, doc) => {
27 | if (!err)
28 | res.redirect('employee/list')
29 | else{
30 | if (err.name === 'ValidationError'){
31 | handleValidationError(err, req.body)
32 | res.render('employee/addOrEdit', {
33 | viewTitle: 'Insert Employee',
34 | employee: req.body
35 | })
36 | }
37 | else{
38 | console.log('Error during record ' + err)
39 | }
40 | }
41 | })
42 | }
43 |
44 | function updateRecord(req, res) {
45 | Employee.findOneAndUpdate({ _id: req.body._id }, req.body, { new: true }, (err, doc) => {
46 | if (!err) {
47 | res.redirect('employee/list')
48 | }else{
49 | if (err.name === "ValidationError") {
50 | handleValidationError(err, req.body)
51 | res.render('employee/addOrEdit', {
52 | viewTitle: 'Update Employee',
53 | employee: doc
54 | })
55 | }else {
56 | console.log('Error during record update: ' + err)
57 | }
58 | }
59 | })
60 | }
61 |
62 | router.get('/list', (req, res) => {
63 | Employee.find((err, docs) => {
64 | if (!err) {
65 | res.render('employee/list', {
66 | list: docs
67 | })
68 | }else{
69 | console.log('Error in employee list: '+ err)
70 | }
71 | }).lean()
72 | })
73 |
74 | function handleValidationError(err, body) {
75 | for (field in err.errors){
76 | switch (err.errors[field].path) {
77 | case 'fullName':
78 | body['fullNameError'] = err.errors[field].message
79 | break
80 | case 'email':
81 | body['emailError'] = err.errors[field].message
82 | break
83 | default:
84 | break
85 | }
86 | }
87 | }
88 |
89 | router.get('/:id', (req, res) => {
90 | Employee.findById(req.params.id, (err, doc) => {
91 | if(!err) {
92 | res.render('employee/addOrEdit', {
93 | viewTitle: 'Изменит работника',
94 | employee: doc
95 | })
96 | }
97 | }).lean()
98 | })
99 |
100 | router.get('/delete/:id', (req, res) => {
101 | Employee.findByIdAndRemove(req.params.id, (err, doc) => {
102 | if (!err) {
103 | res.redirect('/employee/list')
104 | }else{
105 | console.log('Error in processing delete: '+ err)
106 | }
107 | })
108 | })
109 |
110 | module.exports = router
--------------------------------------------------------------------------------