Examples


Express.js - Form Handling


In this tutorial, we will learn how to handle form in Express.js. It calculates the total marks from two inputs and determines if a student has passed or failed based on the marks.

1. Setup Project

Initialize the project

mkdir my-app
cd my-app
npm init -y

Install the dependencies use the command is given below

npm install express hbs

2. Setting Up an Express.js Server

index.js
const express = require('express');
const path = require('path');
const hbs = require('hbs');

const app = express();

// Middleware to parse incoming form data
app.use(express.urlencoded({ extended: true }));

// Serve static files from the public directory
app.use(express.static(path.join(__dirname, 'public')));

// Set up handlebars as the view engine
app.set('view engine', 'hbs');

// Set the location of the views
app.set('views', path.join(__dirname, 'views'));

// Route to serve the form
app.get('/', (req, res) => {
  res.render('index');
});

// Route to handle form submission
app.post('/submit', (req, res) => {
  const { name, mark1, mark2 } = req.body;

  // Convert marks to numbers
  const numMark1 = Number(mark1);
  const numMark2 = Number(mark2);

  // Calculate total marks
  const totalMarks = numMark1 + numMark2;

  // Result: Fail if any mark is below 40
  const result = (numMark1 <= 40 || numMark2 <= 40) ? 'Fail' : 'Pass';

  // Render the result page with name, total, and result
  res.render('result', { name, mark1, mark2, totalMarks, result });

});

const PORT = 5000;

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});

3. Create Handlebars Templates

I) Form Handling Page

This page contains a form where users enter their name and marks. Upon submission, the server processes the data, calculates the total, determines the pass/fail status, and displays the result dynamically.

views/index.hbs
<html>
<head>
    <title>Form Handling</title>
    <link rel="stylesheet" href="/style.css">
</head>
    <body>
        <div class="container">
            <form action="/submit" method="POST">
                <label for="name">Name:</label>
                <input type="text" id="name" name="name" required>

                <label for="mark1">Mark 1:</label>
                <input type="number" id="mark1" name="mark1" required>

                <label for="mark2">Mark 2:</label>
                <input type="number" id="mark2" name="mark2" required>

                <input type="submit" name="submit" value="Submit">
            </form>
        </div>
    </body>
</html>

II) Result Page

The page dynamically presents the submitted form data, showing entered marks, total score, and result. A 'Go Back' link allows users to return and modify their input if needed, ensuring a smooth experience.

views/result.hbs
<html>
<head>
    <title>Result Page</title>
    <link rel="stylesheet" href="/style.css">
</head>
    <body>
        <div class="result-container">
            <h1>Result for <span class="highlight">{{name}}</span></h1>
            <p>Mark 1: <span class="highlight">{{mark1}}</span></p>
            <p>Mark 2: <span class="highlight">{{mark2}}</span></p>
            <p>Total Marks: <span class="highlight">{{totalMarks}}</span></p>
            <p>Result: <span class="highlight">{{result}}</span></p>
            <a href="/">Go back</a>
        </div>
    </body>
</html>

III) Style Page

The form and result container are designed for clarity and usability, with structured spacing, highlighted text, and smooth hover effects for an enhanced user experience.

public/style.css
/* General Reset */
body {
    font-family: 'Arial', sans-serif;
    background-color: #f4f4f9;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

/* Form Container */
.container {
    background: #fff;
    padding: 25px;
    border-radius: 10px;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
    max-width: 400px;
    width: 100%;
}

/* Form Heading */
.container h2 {
    color: #2c3e50;
    font-size: 1.8em;
    margin-bottom: 20px;
    text-align: center;
}

/* Form Labels */
label {
    display: block;
    font-size: 1em;
    color: #555;
    margin-bottom: 5px;
}

/* Form Inputs */
input[type="text"],
input[type="number"] {
    width: 100%;
    padding: 10px;
    font-size: 1em;
    border: 1px solid #ddd;
    border-radius: 5px;
    margin-bottom: 15px;
    box-sizing: border-box;
}

input[type="text"]:focus,
input[type="number"]:focus {
    border-color: #2c3e50;
    outline: none;
}

/* Submit Button */
input[type="submit"] {
    width: 100%;
    background: #2c3e50;
    color: #fff;
    border: none;
    padding: 10px;
    font-size: 1em;
    border-radius: 5px;
    cursor: pointer;
    transition: background 0.3s ease;
}

input[type="submit"]:hover {
    background: #1a252f;
}

/* Result Container */
.result-container {
    max-width: 500px;
    width: 100%;
    padding: 30px;
    background: #fff;
    border-radius: 10px;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
    text-align: center;
}

/* Heading */
h1 {
    color: #2c3e50;
    font-size: 2em;
    margin-bottom: 20px;
}

/* Paragraphs */
p {
    font-size: 1.1em;
    margin: 10px 0;
    color: #555;
}

/* Highlighted Text */
.highlight {
    color: #d6336c;
    font-weight: bold;
}

/* Go Back Link */
a {
    display: inline-block;
    margin-top: 20px;
    padding: 10px 20px;
    background: #2c3e50;
    color: #fff;
    text-decoration: none;
    border-radius: 5px;
    transition: background 0.3s ease;
}

a:hover {
    background: #1a252f;
}

.result-container p {
    text-align: left;
    margin-left: 200px;
}

Run the Server

Run the server using the command is given below.

node index.js
D:\my-app>node index.js
Server is running on http://localhost:5000

Output

Index Page

Express Form handling form output

Result Page

Express Form handling result output