Initializing an Express Application
Begin by creating a fresh Express project with EJS as the view engine.
express backend-panel --view=ejs
cd backend-panel
npm install
To avoid manual server restarts during development, install nodemon globally and adjust the run script.
npm install -g nodemon
Update package.json:
"scripts": {
"start": "node ./bin/www",
"dev": "nodemon ./bin/www"
}
Now launch with npm run dev.
Embedding an Admin Template
Copy the content from an AdminLTE starter page into views/index.ejs. Udpate asset pathss by prefixing them with / and move corresponding CSS/JS folders under public.
Break theLayout into reusable partials: header.ejs, menu.ejs, sidebar.ejs, and footer.ejs. Use EJS includes:
<%- include('header') %>
<%- include('menu') %>
<div>Main content</div>
<%- include('footer') %>
alter menu.ejs to contain links for the dashboard, user management, and product management.
Setting Up Routing and Pages
Create a user management page by copying index.ejs into views/users.ejs. Define its route in routes/users.js:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('users');
});
module.exports = router;
Encoding a similar route for products: create views/pro.ejs and routes/pro.js:
router.get('/', function(req, res) {
res.render('pro');
});
Register the new router in app.js:
var proRouter = require('./routes/pro');
app.use('/pro', proRouter);
Connecting Menu Links and Active States
alter the menu partial to link to /, /users, and /pro.dispatch an identifier to enable the active class:
In routes/index.js:
res.render('index', { selectedMenu: 0 });
In routes/users.js and routes/pro.js, pass selectedMenu: 1 and 2.
In menu.ejs:
<li class="<%- selectedMenu === 0 ? 'active' : '' %>">
<a href="/"><i class="fa fa-dashboard"></i> Dashboard</a>
</li>
MongoDB Integration with Mongoose
Instal the driver:
npm install mongoose@4 --save
Organize database logic in a sql folder:
sql/
collection/
userModel.js
db.js
index.js
sql/collection/userModel.js defines the schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({
userid: String,
username: String,
password: String,
age: Number,
lesson: Number,
sex: Number,
city: String,
company: String
});
module.exports = mongoose.model('User', userSchema);
abstract database operations in sql/index.js (example find, insert, update, delete).
Displaying User Records
In routes/users.js, retrieve data and render to the view:
var User = require('../sql/collection/userModel');
var db = require('../sql');
router.get('/', function(req, res) {
db.find(User, {}, { _id: 0 }).then(users => {
res.render('users', {
selectedMenu: 1,
userList: users
});
});
});
alter the table in users.ejs to iterate over userList:
<% for(var i = 0; i < userList.length; i++) { %>
<tr>
<td><%= i + 1 %></td>
<td><%= userList[i].username %></td>
<td><%= userList[i].age %></td>
<td><%= userList[i].sex === 1 ? 'Male' : 'Female' %></td>
<td><%= userList[i].city %></td>
<td><%= userList[i].company %></td>
<td>
<%= userList[i].lesson === 1 ? 'Phase I' : userList[i].lesson === 2 ? 'Phase II' : 'Phase III' %>
</td>
<td>
<a class="btn" href="/users/update?userid=<%= userList[i].userid %>">
<i class="fa fa-edit"></i>
</a>
<a class="btn" href="/users/delete?userid=<%= userList[i].userid %>">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
<% } %>
Removing a User
Add a delete route:
router.get('/delete', function(req, res) {
db.delete(User, { userid: req.query.userid }).then(() => {
res.redirect('/users');
});
});
Creating a New User
Include a unique identifier using uuid:
npm install uuid --save
alter the scheme to store a userid field.
encoding a separate view views/user_form.ejs with a form. The route for the form:
router.get('/add', function(req, res) {
res.render('user_form', { selectedMenu: 1 });
});
dispatch the form with action="/users/addAction" method="POST".
the handler in routes/users.js:
const { v1: uuidv1 } = require('uuid');
router.post('/addAction', function(req, res) {
let newUser = req.body;
newUser.age = Number(newUser.age);
newUser.lesson = Number(newUser.lesson);
newUser.sex = Number(newUser.sex);
newUser.userid = 'user_' + uuidv1();
db.insert(User, newUser).then(() => {
res.redirect('/users');
});
});
Updating a User
alter the edit link to pass userid.encoding an update page views/user_update.ejs (similar to user_form) with a readonly userid field.
The route to display the form with pre-filled data:
router.get('/update', function(req, res) {
db.find(User, { userid: req.query.userid }).then(data => {
if (data.length) {
res.render('user_update', {
selectedMenu: 1,
...data[0].toObject()
});
}
});
});
After the form submission (action="/users/updateAction" method="POST"):
router.post('/updateAction', function(req, res) {
let updatedData = req.body;
updatedData.age = Number(updatedData.age);
updatedData.lesson = Number(updatedData.lesson);
updatedData.sex = Number(updatedData.sex);
db.update(User, { userid: updatedData.userid }, { $set: updatedData }).then(() => {
res.redirect('/users');
});
});
alter form fields to bind values using EJS syntax, e.g., value="<%= username %>".