Invoice Generator with HTML, CSS & JavaScript
40 DAYS 40 PROJECT CHALLENGE
Day #04
Project Overview
The Invoice Generator is a simple and responsive billing application built using HTML, CSS, and JavaScript. It allows users to create invoices by entering client details, adding multiple items, and calculating the total amount automatically.
Users can enter the client’s name, address, and invoice date. They can also add products or services by specifying the item name, quantity, and price. JavaScript calculates each item’s total and updates the grand total dynamically. Additionally, users can remove items and print the completed invoice using the browser’s print functionality.
This project is useful for learning dynamic table updates, form handling, mathematical calculations, DOM manipulation, and responsive design.
Key Features
- Client Details: Users can enter the client’s name, address, and invoice date through dedicated input fields. These details help organize the invoice according to the customer.
- Add Multiple Items: This project allows users to add multiple products or services by entering the item name, quantity, and price, Each valid item is added to the invoice table.
- Automatic Calculations: The application calculates the total for each item by multiplying its quantity by its price. It also adds all item totals to calculate the grand total.
- Dynamic Invoice Table: Added items appear dynamically inside an HTML table. The table displays the item name, quantity, price, total, and a Remove button.
- Remove Items: Users can remove any item from the invoice by clicking the Remove button. JavaScript updates the item list and recalculates the grand total.
- Input Validation: It checks whether the item name is provided and whether the quantity and price are greater than zero. Invalid details trigger an alert message.
- Real-Time Updates: Whenever an item is added or removed, the invoice table and grand total update automatically without refreshing the page.
- Printable Invoice: Users can click the Print Invoice button to open the browser’s print dialog using the
window.print()method. - Responsive Layout: The client details and add-item sections use Flexbox. On smaller screens, the layout changes to a vertical structure for better usability.
- Simple Billing Interface: The clean layout makes the project suitable for practicing basic invoice and billing interface development for small businesses.
What You'll Learn
- How to structure an invoice generator using HTML.
- How to create forms for client and item details.
- How to use JavaScript arrays to store invoice items.
- How to perform calculations using quantity and price values.
- How to dynamically update HTML tables.
- How to validate numeric and text input fields.
- How to use
parseFloat()for converting input values into numbers. - How to remove array elements using the
splice()method. - How to update page content using DOM manipulation.
- How to use the browser’s
window.print()function. - How to create responsive layouts using Flexbox and media queries.
HTML Code
The HTML structure creates the main invoice interface inside the .container element. It includes a heading titled Invoice Generator and a client details section containing inputs for the client name, client address, invoice date and this add-item section includes three inputs for the item name, quantity, and price. Also the Add Item button calls the addItem() JavaScript function when clicked.
The invoice table contains columns for the item, quantity, price, total, and action. Its <tbody> element uses the invoiceItems ID, allowing JavaScript to insert invoice rows dynamically. The total section displays the grand total using the grandTotal span element. Finally, the Print Invoice button calls the printInvoice() function, and the HTML file connects the external CSS and JavaScript files.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Invoice Generator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h2>Invoice Generator</h2>
<!-- CLIENT DETAILS -->
<div class="client-details">
<input type="text" id="clientName" placeholder="Client Name">
<input type="text" id="clientAddress" placeholder="Client Address">
<input type="date" id="invoiceDate">
</div>
<!-- ADD ITEM -->
<div class="add-item">
<input type="text" id="itemName" placeholder="Item Name">
<input type="number" id="itemQty" placeholder="Qty">
<input type="number" id="itemPrice" placeholder="Price">
<button onclick="addItem()">Add Item</button>
</div>
<!-- TABLE -->
<table>
<thead>
<tr>
<th>Item</th>
<th>Qty</th>
<th>Price</th>
<th>Total</th>
<th>Action</th>
</tr>
</thead>
<tbody id="invoiceItems"></tbody>
</table>
<div class="total-section">
<h3>Grand Total: ₹ <span id="grandTotal">0</span></h3>
</div>
<button class="print-btn" onclick="printInvoice()">Print Invoice</button>
</div>
<script src="script.js"></script>
</body>
</html> CSS Code
The CSS code creates a clean invoice interface with a white content container placed over a dark blue page background. The universal selector uses box-sizing: border-box to make element sizing easier to manage. The .container class sets the invoice’s maximum width to 900px, centers it using margin: 40px auto, and adds padding, rounded corners, and a box shadow. This creates a card-style billing interface.
This .client-details and .add-item classes use Flexbox to arrange their input fields and button horizontally. Their child inputs use flex: 1, allowing them to share the available space. The table uses width: 100% and border-collapse: collapse to create a structured invoice layout.
Also the .total-section selector aligns the grand total to the right. Meanwhile, .print-btn styles the print button with padding, a green background, white text, and a pointer cursor. Finally, the responsive media query targets screens below 768px. It changes the client details and add-item sections to a column layout, making the form easier to use on mobile devices.
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial, sans-serif;
background: #042354;
}
.container {
max-width: 900px;
margin: 40px auto;
background: #fff;
padding: 30px;
border-radius: 10px;
box-shadow: 0 10px 25px rgba(0,0,0,0.08);
}
h2 {
text-align: center;
margin-bottom: 25px;
}
.client-details,
.add-item {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.client-details input,
.add-item input {
flex: 1;
padding: 10px;
}
.add-item button {
padding: 10px 15px;
cursor: pointer;
background: #111;
color: #fff;
border: none;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
table th,
table td {
border: 1px solid #ddd;
padding: 10px;
text-align: center;
}
table th {
background: #f1f1f1;
}
.total-section {
text-align: right;
margin-top: 20px;
}
.print-btn {
margin-top: 20px;
padding: 12px 20px;
background: green;
color: #fff;
border: none;
cursor: pointer;
}
/* RESPONSIVE */
@media(max-width: 768px) {
.client-details,
.add-item {
flex-direction: column;
}
} Javascript Code
items array stores the invoice items, while the grandTotal variable tracks the combined total. The addItem() function retrieves the item name, quantity, and price using document.getElementById(). It converts the quantity and price into numbers with parseFloat(). If the item name is empty or the quantity or price is less than or equal to zero, the function displays an alert and stops execution.After validation, the function calculates the item total by multiplying the quantity by the price. It then adds the item as an object to the items array and calls updateTable(). Finally, it clears the item input fields. The updateTable() function clears the existing table rows and resets the grand total to zero. It uses forEach() to loop through the items array, add each item’s total to the grand total, and generate table rows dynamically using template literals. The function also updates the grandTotal element with the calculated amount.
The removeItem() function removes an item from the array using splice() and calls updateTable() again. Finally, the printInvoice() function uses window.print() to open the browser’s print dialog.
let items = [];
let grandTotal = 0;
function addItem() {
const name = document.getElementById("itemName").value;
const qty = parseFloat(document.getElementById("itemQty").value);
const price = parseFloat(document.getElementById("itemPrice").value);
if (!name || qty <= 0 || price <= 0) {
alert("Please enter valid item details");
return;
}
const total = qty * price;
items.push({ name, qty, price, total });
updateTable();
document.getElementById("itemName").value = "";
document.getElementById("itemQty").value = "";
document.getElementById("itemPrice").value = "";
}
function updateTable() {
const tbody = document.getElementById("invoiceItems");
tbody.innerHTML = "";
grandTotal = 0;
items.forEach((item, index) => {
grandTotal += item.total;
tbody.innerHTML += `
<tr>
<td>${item.name}</td>
<td>${item.qty}</td>
<td>₹${item.price}</td>
<td>₹${item.total}</td>
<td><button onclick="removeItem(${index})">Remove</button></td>
</tr>
`;
});
document.getElementById("grandTotal").innerText = grandTotal;
}
function removeItem(index) {
items.splice(index, 1);
updateTable();
}
function printInvoice() {
window.print();
} Related Projects
Day 1 : Admin Dashboard UI
User signup and login system with validated credentials and a clean UI.
Concepts: DOM manipulation, form validation, LocalStorage.
Day 2 : Kanban Board (Drag & Drop)
A drag-and-drop task board to manage tasks across different stages.
Concepts: DOM manipulation, drag & drop API, event handling.
Day 6 : File Upload Progress Bar
File upload interface with a visual progress bar and smooth animation.
Concepts: File API, progress tracking, animations, event handling.