Skip to content

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

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

html
<!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

html
<!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
  1. Open your web browser and navigate to http://localhost:3000.

  2. Fill in your name and email.

  3. Click the "Choose File" button and select an image from your computer.

  4. Click Submit.

  5. 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 an uploads/ 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.

js
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.

html
<!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.

html
<!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>

Made with ❤️ for students, by a fellow learner.