Express: EJS Feedback Application
Design a feedback form for a travel website using Express.
- The form should collect the user's name, email, and a description of an issue.
- On successful submission, display the text input using EJS.
Project Structure
/feedback-app
├── /views
│ ├── feedback.ejs
│ └── result.ejs
├── package.json
└── server.js
server.js
import express from 'express';
const app = express();
const port = 3001;
// --- Middleware Setup ---
// Set EJS as the view engine
app.set('view engine', 'ejs');
// middleware to parse the URL-encoded data from the form submission.
app.use(express.urlencoded({ extended: true }));
// --- Routes ---
// Route to display the feedback form
app.get('/', (req, res) => {
res.render('feedback');
});
// Route to handle the form submission
app.post('/submit', (req, res) => {
// Destructure data from the request body
const { name, email, issue } = req.body;
// Render the result page with the submitted data
res.render('result', { name, email, issue });
});
// --- Start Server ---
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
views/feedback.ejs
CSS Is extra
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Travel Feedback</title>
<style>
body { font-family: sans-serif; background-color: #f4f4f9; padding: 2em; }
.form-container { max-width: 500px; margin: auto; padding: 2em; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
input, textarea, button { width: 100%; padding: 10px; margin-top: 5px; border: 1px solid #ccc; border-radius: 4px; }
button { background-color: #007bff; color: white; cursor: pointer; border: none; }
</style>
</head>
<body>
<div class="form-container">
<h1>Submit Feedback</h1>
<form action="/submit" method="POST">
<div>
<label for="name">Name:</label><br>
<input type="text" id="name" name="name" required>
</div>
<br>
<div>
<label for="email">Email:</label><br>
<input type="email" id="email" name="email" required>
</div>
<br>
<div>
<label for="issue">Description of the issue:</label><br>
<textarea id="issue" name="issue" rows="6" required></textarea>
</div>
<br>
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>
views/result.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Feedback Submitted</title>
<style>
body { font-family: sans-serif; background-color: #f4f4f9; padding: 2em; text-align: center; }
.result-container { max-width: 500px; margin: auto; padding: 2em; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
p { text-align: left; }
</style>
</head>
<body>
<div class="result-container">
<h1>Thank You for Your Feedback!</h1>
<hr>
<p><strong>Name:</strong> <%= name %></p>
<p><strong>Email:</strong> <%= email %></p>
<p><strong>Issue:</strong> <%= issue %></p>
</div>
</body>
</html>
Run and Test
npm init -y
npm install express ejs
Then, ensure your package.json
includes "type": "module"
.
node app.js
Open your web browser and navigate to
http://localhost:3000
.Fill in your name and email.
Click the "Choose File" button and select an image from your computer.
Click Submit.
You will be redirected to the success page, which will display the name and email you entered, along with a preview of the image you uploaded. You can also check your project folder to see the image file saved in the
uploads
directory.
Actual Question
Design a feedback form for a travel website using Express and multer.
- The form should collect the user's name, email, and a screenshot of an issue.
- Use
multer.diskStorage()
to configure multer to save the uploaded image to anuploads/
folder. - On successful submission, display the text input and a preview of the uploaded image back to the user using EJS.
Directory Structure
The uploads
folder will be created automatically by the application when the first file is uploaded.
/feedback-form-app
├── uploads/ <-- Multer will save images here
├── views/
│ ├── form.ejs
│ └── success.ejs
├── app.js
└── package.json
app.js
This file sets up the Express server, configures multer
for file storage, and defines the routes to render the form and handle the submission.
import express from 'express';
import path from 'path';
import multer from 'multer';
import { fileURLToPath } from 'url';
const app = express();
const PORT = 3000;
// Needed for __dirname in ES Modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Set EJS as the view engine
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// Middleware to parse URL-encoded form data
app.use(express.urlencoded({ extended: true }));
// Serve uploaded files statically
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
// --- Multer Configuration ---
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/'); // Set the destination folder for uploads
},
filename: (req, file, cb) => {
// Create a unique filename to avoid overwrites
cb(null, Date.now() + '-' + file.originalname);
}
});
const upload = multer({ storage: storage });
// --- Routes ---
// GET / - Display the feedback form
app.get('/', (req, res) => {
res.render('form');
});
// POST /submit-feedback - Handle form submission with file upload
app.post('/submit-feedback', upload.single('screenshot'), (req, res) => {
const { name, email } = req.body;
const image = req.file; // Multer adds the file object to the request
// Render a success page displaying the submitted data and image
res.render('success', { name, email, image });
});
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
EJS Files
views/form.ejs
This file contains the HTML form. The enctype="multipart/form-data"
attribute is essential for file uploads.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Feedback Form</title>
</head>
<body>
<h1>Submit Feedback</h1>
<form action="/submit-feedback" method="POST" enctype="multipart/form-data">
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
</div>
<br>
<div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<br>
<div>
<label for="screenshot">Screenshot of Issue:</label>
<input type="file" id="screenshot" name="screenshot" accept="image/*" required>
</div>
<br>
<button type="submit">Submit</button>
</form>
</body>
</html>
views/success.ejs
This page is rendered after a successful submission, showing the user's input and a preview of their uploaded image.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Submission Successful</title>
</head>
<body>
<h1>Thank You, <%= name %>!</h1>
<p>We have received your feedback. A confirmation has been sent to <%= email %>.</p>
<h2>Your Uploaded Screenshot:</h2>
<% if (image) { %>
<img src="/uploads/<%= image.filename %>" alt="Uploaded Screenshot" width="500">
<% } else { %>
<p>No image was uploaded.</p>
<% } %>
</body>
</html>