Javascript code
require('dotenv').config();
const express = require("express");
const path = require("path");
const crypto = require("crypto");
const multer = require("multer");
const {GridFsStorage} = require('multer-gridfs-storage');
const Grid = require("gridfs-stream");
const methodOverride = require("method-override");
const bodyParser = require("body-parser");
const ejs = require("ejs");
const mongoose = require("mongoose");
const session = require("express-session");
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const findOrCreate = require("mongoose-findorcreate")
const app = express();
app.set('view engine', 'ejs');
app.use(bodyParser.json());
app.use(methodOverride('_method'));
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static("public"));
const mongoURI = 'mongodb://127.0.0.1:27017/userDB';
const conn = mongoose.createConnection(mongoURI);
//mongoose.connect("mongodb://127.0.0.1:27017/userDB", {useNewUrlParser: true});
let posts = [];
let gfs, gridfsBucket;
conn.once("open",() => {
gridfsBucket = new mongoose.mongo.GridFSBucket(conn.db, {
bucketName: "upload"
});
gfs = Grid(conn.db, mongoose.mongo);
gfs.collection("upload");
});
const storage = new GridFsStorage({
url: mongoURI,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if(err) {
return reject(err);
}
const filename = buf.toString("hex") + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: "upload"
};
resolve(fileInfo);
});
});
}
});
const upload = multer({storage});
app.get("/", function(req, res){
res.render("review");
});
app.post("/review", (req, res) => {
const post = {
name: req.body.userName,
hotel: req.body.hotelName,
address: req.body.hotelAddress,
star: req.body.rating,
userexperience: req.body.experience
};
posts.push(post);
//res.json({ file: req.file});
res.redirect("/content");
});
app.get("/content", function(req, res){
gfs.files.find().toArray((err, files) => {
// Check if files
if (!files || files.length === 0) {
res.render("content", {files: false});
} else {
files.map(file => {
if(file.contentType === "image/jpeg" || file.contentType === "image/png"){
file.isImage = true;
}else{
file.isImage = false;
}
});
res.render("content", {files: files});
}
});
});
app.get("/content", function(req, res){
res.render("content", {posts: posts});
});
//#route GET /files
//#desc Display all files in JSON
app.get("/files", (req, res) => {
gfs.files.find().toArray((err, files) => {
// Check if files
if (!files || files.length === 0) {
return res.status(404).json({
err: "No files exist"
});
}
// Files exist
return res.json(files);
});
});
app.get("/files/:filename", (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
// Check if file
if (!file || file.length === 0) {
return res.status(404).json({
err: "No file exists"
});
}
// File exists
return res.json(file);
});
});
// #route GET /image/:filename
// #desc Display Image
app.get("/image/:filename", (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
// Check if file
if (!file || file.length === 0) {
return res.status(404).json({
err: "No file exists"
});
}
// Check if image
if (file.contentType === "image/jpeg" || file.contentType === "image/png") {
// Read output to browser
const readstream = gridfsBucket.openDownloadStreamByName(file.filename);
readstream.pipe(res);
} else {
res.status(404).json({
err: "Not an image"
});
}
});
});
// Server setup
app.listen(3000, function(req, res) {
console.log("Connected on port:3000");
});
HTML Code where the review should be displayed - this is content page
<section class="review-content">
<% posts.forEach(function(post){ %>
<h6><b>User Name:</b><%=post.name%></h6>
<h5><b>Hotel Name:</b><%=post.hotel%></h5>
<p><b>Hotel Address:</b><%=post.address%></p>
<%if(post.star == 5){%>
<p><b>Rating: </b>⭐⭐⭐⭐⭐ - Luxury</p>
<%}%>
<%if(post.star == 4){%>
<p><b>Rating: </b>⭐⭐⭐⭐ - First Class</p>
<%}%>
<%if(post.star == 3){%>
<p><b>Rating: </b>⭐⭐⭐ - Comfort</p>
<%}%>
<%if(post.star == 2){%>
<p><b>Rating: </b>⭐⭐ - Standard</p>
<%}%>
<%if(post.star == 1){%>
<p><b>Rating: </b>⭐ - Basic</p>
<%}%>
<% if(files){ %>
<% files.forEach(function(file) { %>
<% if(file.isImage) { %>
<img src="image/<%= file.filename %>" alt="">
<% } %>
<% }) %>
<% } else { %>
<p>No files to show</p>
<% } %
<p><b>User experience:</b><%=post.userexperience%></p>
<%});%>
HTML Code where the review should be displayed - this is review page
<form class="" action="/review" method="post" enctype="application/x-www-form-urlencoded" enctype="multipart/form-data" action="submit.php">
<section class="review-section-height">
<section class="review-section">
<div class="review-section-div">
<div class="user-name-review">
<label for="hotel-name">User Name:</label>
<input type="text" id="user-id-name" name="userName" placeholder="User Name" size="40"><br>
</div>
<div class="review-hotel-name">
<label for="hotel-name">Hotel Name:</label>
<input type="text" id="hotel-id-name" name="hotelName" placeholder="Hotel Name" size="40"><br>
</div>
<div class="hotel-address-div">
<label for="hotel-address-name">Hotel Address:</label>
<input type="text" id="hotel-id-address" name="hotelAddress" placeholder="Hotel Address" size="40"><br>
</div>
</div>
</section>
<section class="star-rating-section">
<div class="food-experience-div">
<h5>Rate your experience in hotel:</h5>
<div class="rating">
<input type="radio" name="rating" value="5" id="5"><label for="5">☆</label>
<input type="radio" name="rating" value="4" id="4"><label for="4">☆</label>
<input type="radio" name="rating" value="3" id="3"><label for="3">☆</label>
<input type="radio" name="rating" value="2" id="2"><label for="2">☆</label>
<input type="radio" name="rating" value="1" id="1"><label for="1">☆</label>
</div>
</div>
</section>
</section>
<div class="container">
<div class="wrapper">
<div class="image">
<img width="50%" height="450vh" src="" alt="">
</div>
<div class="content">
<div class="icon">
<i class="fas fa-cloud-upload-alt"></i>
</div>
<div class="text">
No file chosen, yet!
</div>
</div>
<div id="cancel-btn">
<i class="fas fa-times"></i>
</div>
<div class="file-name">
File name here
</div>
</div>
<input name="file" id="default-btnn" type="file" >
</div>
<section class="overall-user-review">
<div class="overall-user-review-div">
<label for="experience-write-box">Write your experience:</label><br>
<textarea class="experience-textarea" name="experience" rows="10" cols="47" placeholder="Elaborate your experince in the hotel..."></textarea>
</div>
</section>
<script>
const wrapper = document.querySelector(".wrapper");
const fileName = document.querySelector(".file-name");
const defaultBtn = document.querySelector("#default-btnn");
const customBtn = document.querySelector("#custom-btn");
const cancelBtn = document.querySelector("#cancel-btn i");
const img = document.querySelector("img");
let regExp = /[0-9a-zA-Z\^\&\'\#\{\}\[\]\,\$\=\!\-\#\(\)\.\%\+\~\_ ]+$/;
function defaultBtnActive() {
defaultBtnn.click();
}
defaultBtn.addEventListener("change", function() {
const file = this.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function() {
const result = reader.result;
img.src = result;
wrapper.classList.add("active");
}
cancelBtn.addEventListener("click", function() {
img.src = "";
wrapper.classList.remove("active");
})
reader.readAsDataURL(file);
}
if (this.value) {
let valueStore = this.value.match(regExp);
fileName.textContent = valueStore;
}
});
</script>
[Output at hyper terminal]
[Output at localhost at chrome]
Looking forward if someone can help me with this...
I need both image and text to be rendered on the screen
I am stuck with this problem for several days...
It's saying posts not defined... at eval... and so on...
Hoping a positive reply from developers...
Thank you for your help...
Related
I'm developing an application with Node.js and EJS but there is an error. It says "msg_type is not defined". When I'm using handlebars, there is no problem. What is my mistake. Actually, when url goes to /auth/login , the message is displaying but it's not displaying in /login routing.
my users.js file (controllers)
exports.login = async (req, res,next) => {
try {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).render("login", {
msg: "Kullanıcı Adınız veya Parolanız Hatalı",
msg_type: "error",
},
next()
);
}
await login_db.query(
"select * from users where email=?",
[email],
async (error, result) => {
console.log(result);
if (result.length <= 0) {
return res.status(401).render("login", {
msg: "E-mailiniz veya Parolanız Hatalı",
msg_type: "error",
});
} else {
if (!(await bcrypt.compare(password, result[0].PASS))) {
return res.status(401).render("login", {
msg: "E-mailiniz veya Parolanız Hatalı",
msg_type: "error",
});
} else {
const id = result[0].ID;
const token = jwt.sign({ id: id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRES_IN,
});
console.log("The Token is " + token);
const cookieOptions = {
expires: new Date(
Date.now() +
process.env.JWT_COOKIE_EXPIRES * 24 * 60 * 60 * 1000
),
httpOnly: true,
};
res.cookie("joes", token, cookieOptions);
res.status(200).redirect("/anasayfa");
}
}
}
);
} catch (error) {
console.log(error);
}
};
my auth.js file
const express = require("express");
const userController = require("../controllers/users");
const router = express.Router();
router.post("/login", userController.login);
my login.ejs file
<% if (true) { %>
<p class="<%= msg_type %>"><%= msg %> </p>
<% } %>
<form action="/auth/login" method="post">
<div class="data">
<label for="email">Email</label>
<input type="email" name="email" id="email" />
</div>
<div class="data">
<label for="password">Şifre</label>
<input type="password" name="password" id="password" />
</div>
<div class="forgot-pass">
Şifrenizi mi unuttunuz?
</div>
<div class="btn">
<button type="submit">Giriş Yap</button>
</div>
<div class="signup-link">
Kayıtlı değil misin? Şimdi Kayıt Ol!
</div>
</form>
my app.js file
app.use("/", require("./routes/pages"));
app.use("/auth", require("./routes/auth"))
;
my pages.js file
router.get(["/", "/login"], (req, res) => {
//res.send("<h1>Hello Tutor Joes Salem</h1>");
res.render("login");
});
The variable should be exported from the original file(users.js) and also should be imported in login.ejs, so you can use it without problems, this is how things work in Javascript.
I have this express server and whenever you post username or password 1 or 1=1 it will not respond. there will be no console output or errors. And it will keep working after that.
I have tried adding app.post("*") at the top of the code and it won't even fire the event (so its not sql or the app.use).
If you want to test it go to https://speedcubing.top/login
index.js
const cubing = require('./cubing.js')
const mysql = require('./SQL.js')
const express = require('express')
const cookies = require('cookie-parser')
const uuid = require('uuid')
const app = express()
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
app.use(cookies())
app.use(express.static('static'))
//database
const sql = new mysql('localhost', 'user', 'pass')
const systemdb = sql.database('speedcubingsystem')
//use
app.use(async (req, res, next) => {
cubing.info("use")
let redir = false
if (req.url.endsWith('/') && req.url != '/') {
redir = true
req.url = req.url.slice(0, -1)
}
if (req.subdomains[0] == 'www') {
redir = true
}
if (req.url.includes('?')) {
redir = true
req.url = req.url.split('?')[0]
}
if (redir)
res.redirect('https://speedcubing.top' + req.url)
else {
if (req.url != 'myip') {
req.loginName = ''
req.admin = false
if (req.cookies.login !== undefined) {
const result = await systemdb.query("SELECT user,admin FROM web_user WHERE token='" + req.cookies.login.token + "'")
if (result.length > 0) {
req.loginName = result[0].user
req.admin = result[0].admin.lastIndexOf(1) !== -1
}
}
}
next()
}
})
//index page
app.get('/', async (req, res) => {
res.render('index.ejs', {
loginName: req.loginName,
})
})
//login page
app.post('/login', async (req, res) => {
cubing.info("post login")
const name = mysql.validateString(req.body.username)
const pw = mysql.validateString(req.body.password)
if ((await systemdb.query('SELECT * FROM web_user WHERE user=' + name + ' AND password=' + pw)).length > 0) {
const token = uuid.v4()
systemdb.query("UPDATE web_user SET token='" + token + "' WHERE user=" + name + ' AND password=' + pw)
res.cookie('login', { token: token }, { httpOnly: false })
res.redirect('/')
} else res.render('login.ejs', {
loginName: req.loginName,
error: true,
})
})
app.get('/login', async (req, res) => {
cubing.info("get login")
if (req.loginName != '')
res.redirect('https://speedcubing.top')
else res.render('login.ejs', {
loginName: '',
error: false
})
})
//logout
app.get('/logout', async (req, res) => {
res.clearCookie('login')
res.redirect('/')
})
app.listen(25080, function () {
cubing.info('Listening on /0.0.0.0:25080')
})
login.ejs
<title>speedcubing.top</title>
<html>
<head>
<link rel="stylesheet" href="/a.css">
</head>
<body><div class="wrapper">
<%- include("./global/header.ejs") %>
<table width="200" border="0" align="center">
<tr><td>
<form action="login" method="post">
<% if(error !== undefined && error){%>
<p><%= "invalid usr/pw" %></p>
<% } %>
username: <input type="text" name="username" ><br/>
password: <input type="password" name="password" ><br/>
<input type="submit" value="login">
</form>
</td></tr>
</table>
</div>
<%- include("./global/footer.ejs") %>
</body>
</html>
my index.js file and views/products/edit.ejs files :
const express = require('express')
const path = require('path')
const mongoose = require('mongoose');
const methodOverride = require('method-override')
const app = express()
app.set('view engine', 'ejs')
app.set('views', path.join(__dirname, "views"))
app.use(express.urlencoded({
extended: true
}))
app.use(methodOverride('_method'))
mongoose.connect('mongodb://localhost:27017/farmStand')
.then((data) => {
console.log("successfully connected to database")
console.log(data)
}).catch(error => {
console.log("error occured")
console.log(error)
})
function wrapperASync(fn) {
return function(req, resp, next) {
fn(req, resp, next).catch((e) => {
next(e)
})
}
}
let categories = ['fruits', 'vegetables', 'dairy']
const Product = require('./models/product');
const {
param
} = require('express/lib/request');
app.get('/', (req, resp) => {
resp.send("getting data")
})
app.get('/products', async(req, resp) => {
const {
category
} = req.query
const selectedcategory = category
console.log(selectedcategory)
if (selectedcategory) {
let products = await Product.find({
category: selectedcategory
})
resp.render("products/index", {
products,
selectedcategory
})
} else {
let products = await Product.find({})
// console.log("found products")
resp.render("products/index", {
products,
selectedcategory: "All"
})
}
})
app.get('/products/:id', async(req, resp, next) => {
const {
id
} = req.params
let myproduct = await Product.findById(id)
if (!myproduct) {
return next(new AppError("product not found", 404))
}
// console.log(myproduct)
resp.render('products/details', {
myproduct
})
})
app.get('/product/new', (req, resp) => {
resp.render('products/new', {
categories
})
})
app.get('/products/:id/edit', wrapperASync(async(req, resp, next) => {
const {
id
} = req.params
const product = await Product.findById(id)
if (!product) {
throw new AppError("product not found", 404)
}
resp.render('products/edit', {
product,
categories
})
}))
app.put('/products/:id', wrapperASync(async(req, resp, next) => {
const {
id
} = req.params
const updatedValues = req.body
const newvalue = await Product.findByIdAndUpdate(id, updatedValues, {
runValidators: true,
new: true
})
// console.log(newvalue)
resp.redirect(`/products/${newvalue._id}`)
}))
app.post('/products', wrapperASync(async(req, resp) => {
const newdoc = req.body
const myproduct = new Product(newdoc)
console.log(myproduct)
await myproduct.save()
resp.redirect(`/products/${myproduct._id}`)
}))
app.delete('/products/:id', async(req, resp, next) => {
try {
const {
id
} = req.params
const deleted_product = await Product.findOneAndDelete(id)
resp.redirect('/products')
} catch (error) {
next(error)
}
})
app.use((err, req, resp, next) => {
console.log(err.name)
next(err)
})
app.use((err, req, resp, next) => {
const {
status = 404, message = "something went wrong"
} = err
resp.status(status).send(message)
})
app.listen(3000, () => {
console.log("server started successfully")
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1> enter product details</h1>
<form action="/products/<%= product.id %>?_method=PUT " method="POST">
<label for="name">enter the name of the product : </label>
<input type="text" name="name" id="name" placeholder="name" value="<%= product.name %> ">
<label for="price">enter the price in dollars : </label>
<input type="number" name="price" id="price" placeholder="price" value="<%= product.price %>">
<label for="category">category : </label>
<select name="category" id="category">
<% for(category of categories) { %>
<option value="<%= category %>" <%=p roduct.category===c ategory ? "selected": '' %> >
<%= category %>
</option>
<% } %>
</select>
<button>add new details</button>
</form>
<section>
exit
</section>
</body>
</html>
my models/product.js file :
const mongoose = require('mongoose')
const productSchema = new mongoose.Schema({
name : {
type : String,
required : true
},
price:{
type : Number,
required : true,
min : 0
},
category:{
type:String,
lowercase :true,
enum : ["fruits","vegetables","dairy"]
}
})
const Product = new mongoose.model('Product',productSchema);
module.exports = Product;
my problem : I have installed all the dependencies my problem is when I am entering in to the edit page and then when I type my id incorrect and of different length in the url for which Iam listening for I get the CastError printed out on my console and when I keep my name Field as blank and edit then I get the ValidationError printed out on my console but after getting the validation error when I change the id of the product which is incorrect again and which is of different length in the url after getting validation error response and send the request in chrome my server gets error and breaks even though I handle the error of my /products/:id put route
please help me
Maybe this is an already answered question but I can't seem to find the right answer for me. I can't see what's wrong with my code.
I have a form to upload the specifics of a vehicle such as route, price, a picture of the vehicle, etc. When I get the url of the image, it doesn't display anything
example image
Here's the code I use to post my form
//POST create vehicle
app.post('/createVehicle', async function(req, res, next){
const fileData = new Parse.File("VehiclePic", { base64: req.body.VehicleImg }, "image/png");
console.log(fileData);
let car = new Car();
const Vehicle = {
VehicleImg: fileData,
Name: req.body.Name,
description: req.body.description,
Price: parseInt(req.body.Price),
Route: req.body.Route,
PassengerAmount: parseInt(req.body.PassengerAmount)
}
try{
fileData.save().then(saved => {
car.set('Image', saved);
car.set('Name', Vehicle.Name);
car.set('Description', Vehicle.description);
car.set('Route', Vehicle.Route);
car.set('Price', Vehicle.Price);
car.set('PassengerAmount', Vehicle.PassengerAmount);
console.log("URL vehiculo " + saved.url());
car.save();
console.log("El vehiculo ha sido creado con exito!");
})
}catch(error){
console.error('error ' , error);
}
res.redirect('/');
});
The reason I don't use Vehicle.VehicleImg is because it returns me an undefined object.
Here's the code to get all data
const Car = Parse.Object.extend('Vehicle');
const query = new Parse.Query(Car);
app.get('/', async function(req, res) {
const VehicleInfo = [];
query.notEqualTo("objectId", null);
try {
const result = await query.find();
result.forEach(vehicle => {
const vehiclePic = vehicle.get('Image');
VehicleInfo.push({
VehicleID: vehicle.id,
VehicleImage: vehiclePic,
VehicleName: vehicle.get('Name'),
Description: vehicle.get('Description'),
Price: vehicle.get('Price'),
Rating: vehicle.get('Rating'),
Route: vehicle.get('Route'),
PassengerAmount: vehicle.get('PassengerAmount')
});
});
res.render('index', {
title: 'MainPage',
VehicleData: VehicleInfo
});
} catch (error) {
console.error('error fetching objects', error);
}
});
EDIT:this is the form, I'm using ejs.
<div class="createVehicle-section container">
<br>
<form method="POST" action="/createVehicle" enctype="multipart/form-data">
<div id="img">
<label for="VehicleImg">Seleccione la imagen:</label>
<input type="file" id="VehicleImg" name="VehicleImg" >
</div>
<br>
<div class="col-lg-12 row">
<div class="col-md-6">
<label for="VehicleName">Nombre del vehiculo</label>
<input type="text" id="VehicleName" name="Name">
<br>
<label for="DescriptionVe">Descripción</label>
<input type="text" id="Descriptionve" name="description">
</div>
<div class="col-md-6">
<label for="PriceVe">Precio</label>
<input type="number" id="PriceVe" name="Price" min="0" max="9999">
<br>
<label for="RouteVe">Ruta</label>
<input type="text" id="RouteVe" name="Route">
</div>
</div>
<br>
<div class="col-md-6 container">
<label for="PassegerAmountVe">Cantidad de Pasajeros Permitida</label>
<input type="number" id="PassengerAmountVe" name="PassengerAmount" min="0" max="9999">
</div>
<br>
<div class="text-center">
<input class="btn btn-main btn-lg btn-shadow" type="submit" value="Guardar"/>
</div>
</form>
<br>
</div>
EDIT: Here's my multer code to upload it to a localstorage, and I need to upload it to back4app.
//Multer Image Storage
const storage = multer.diskStorage({
destination: './public/images/',
filename: function(req, file, cb){ //cb = callback
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
// Init Upload
const upload = multer({
storage: storage,
limits:{fieldSize: 1000000},
fileFilter: function(req, file, cb){
checkFileType(file, cb);
}
}).single('VehicleImg');
Try the following code:
const upload = multer();
app.post('/createVehicle', upload.single('VehicleImg'), async function(req, res, next){
const fileData = new Parse.File("VehiclePic.png", [...req.file.buffer], "image/png");
console.log(fileData);
let car = new Car();
const Vehicle = {
VehicleImg: fileData,
Name: req.body.Name,
description: req.body.description,
Price: parseInt(req.body.Price),
Route: req.body.Route,
PassengerAmount: parseInt(req.body.PassengerAmount)
}
try{
fileData.save().then(saved => {
car.set('Image', saved);
car.set('Name', Vehicle.Name);
car.set('Description', Vehicle.description);
car.set('Route', Vehicle.Route);
car.set('Price', Vehicle.Price);
car.set('PassengerAmount', Vehicle.PassengerAmount);
console.log("URL vehiculo " + saved.url());
car.save();
console.log("El vehiculo ha sido creado con exito!");
})
}catch(error){
console.error('error ' , error);
}
res.redirect('/');
});
I was trying to implement a website where there is a driver and passenger(carpool).
So when a driver gives his details and clicks submit he goes to a URL (select) where he can choose the passenger which he wants.
I have written the following snippet:-
app.post('/passenger',function(req,res){
var user = new User({profile:{name:req.body.uname},
type:"passenger",
phone_no:req.body.contact,
origin:{city:req.body.pick},
destination:{city:req.body.drop}
// email:req.body.email,
// password:req.body.password
})
user.save();
res.redirect('/');
});
app.post('/driver',function(req,res){
var user = new User({profile:{name:req.body.uname},
type:"driver",
phone_no:req.body.contact,
origin:{city:req.body.pick},
destination:{city:req.body.drop}
// email:req.body.email,
// password:req.body.password
})
user.save();
console.log("heyyyy")
res.redirect('/select');
});
app.get('/select',function(req,res){
// User.find(function(err,type){
// res.render('select',{type:type});
// });
if (req.user){
console.log("U are inside")
if(req.user.type="passenger")
{
res.render('select');
}
else{
res.send("You ar not admin");
}
}
console.log("u are outside")
console.log(req.body.uname)
console.log()
});
The values are getting saved in the database but I am not able to retrieve the information (i.e. the list of all the passengers).
I am not able to process it (i.e. giving error).
Please help me out..
It is hard to pinpoint the source of the problem without knowing how you are configuring your express server anyway I have created an example based on your context.
app.js file:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var engine = require('ejs-locals');
var querystring = require('querystring');
var drivers = [];
var passengers = [{name: 'Wilson'}, {name: 'Raul'}];
app.engine('ejs', engine);
app.set('view engine', 'ejs');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.get('/', function(req, res) {
res.render('driver');
});
app.post('/driver', function(req, res) {
var driver = {
name: req.body.name,
age: req.body.age
};
drivers.push(driver);
var data = {
driver: driver,
passengers: passengers
};
res.render('passengers', data);
});
app.get('/result', function(req, res) {
var data = {
driverName: '',
passengerNames: []
};
data.driverName = req.query.driverName;
data.passengerNames = data.passengerNames.concat(req.query.passengerNames);
res.render('result', data);
});
app.post('/api/passengers', function(req, res) {
var data = {
passengerNames: req.body.passengerNames,
driverName: req.body.driverName
};
var qs = querystring.stringify(data);
res.redirect('/result?' + qs);
});
app.listen(4040, function() {
console.log('server up and running at port 4040');
});
views/layout.ejs file:
<!doctype html>
<html>
<head>
<title>Drivers App</title>
</head>
<body>
<div id="app">
<%- body %>
</div>
<script>
document.addEventListener('DOMContentLoaded', function(e) {
var btnNext = document.getElementById('btnNext');
btnNext.onclick = function(e) {
var allPassengers = document.querySelectorAll('input[type=checkbox]');
var selectedPassengers = [].filter.call(allPassengers, function(p) {
return p.checked;
});
var passengerNames = [].map.call(selectedPassengers, function(p) {
return p.value;
});
var driverName = document.getElementById('driverName').innerHTML;
var r = new XMLHttpRequest();
r.open('POST', '/api/passengers');
r.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
r.onreadystatechange = function() {
if (r.readyState != 4 || r.status != 200) return;
document.getElementById('app').innerHTML = r.responseText;
};
r.send(JSON.stringify({
passengerNames: passengerNames,
driverName: driverName
}));
};
});
</script>
</body>
</html>
views/driver.ejs file:
<% layout('layout.ejs') -%>
<h1> Driver </h1>
<form method="POST" action="/driver">
<label>Name:</label>
<input id="name" name="name" type="text"/>
<br />
<label>Age:</label>
<input id="age" name="age" type="text"/>
<br />
<br />
<input type="submit" value="Submit" />
</form>
`views/passengers.ejs`
<% layout('layout') -%>
<h1> Driver </h1>
<p>Name: <span id="driverName"><%= driver.name%></span></p>
<h1> Passengers </h1>
<% passengers.forEach(function(p) {%>
<input type="checkbox" value=<%= p.name %> /> <%= p.name %> <br />
<% }); %>
<br />
<button id="btnNext">Next</button>
views/result.ejs file:
<h1>Success!</h1>
<h2>Driver</h2>
<h3><%= driverName %></h3>
<br />
<h2>Selected Passengers</h2>
<% passengerNames.forEach(function(name) { %>
<h3><%= name%></h3>
<% }); %>