Day 29: JavaScript Mini Project: Build a Form Validator, Calculator, or Dynamic UI πŸš€

Lokesh Prajapati
5 min read4 days ago

JavaScript Mini Project: Build a Form Validator, Calculator, or Dynamic UI πŸš€

Building small projects is the best way to reinforce JavaScript concepts. In this post, we will create three mini-projects:

βœ… Form Validation β€” Ensure user input is correct before submission.
βœ… Calculator β€” A simple yet functional arithmetic calculator.
βœ… Dynamic UI Component (FAQ Accordion) β€” Expand/collapse sections dynamically.

πŸ“Œ Project 1: Form Validation

Form validation ensures that users provide the correct data before submitting a form.

πŸ”Ή What is Form Validation?

Form validation is a technique to check user input before processing it. It can be client-side (JavaScript) or server-side (backend validation).

πŸ›  How It Works?

  • JavaScript listens for form submission.
  • It checks the input fields for correct data.
  • If the input is invalid, an error message is displayed.
  • If valid, the form is submitted.

πŸ“Œ Code Implementation:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Form Validation</title>
<style>
* {
box-sizing: border-box;
clear: both;
}

.container {
max-width: 500px;
background: gainsboro;
box-sizing: border-box;
border-radius: 5px;
padding: 20px;
margin: 0 auto;
}

.error-message {
color: red;
font-size: 14px;
display: block;
margin-top: 5px;
}

.success-message {
color: green;
font-weight: bold;
}

input {
display: block;
margin: 10px 0;
padding: 8px;
width: 100%;
border: 1px solid #ccc;
border-radius: 5px;
}

input.error {
border-color: red;
}

button {
padding: 8px 15px;
border-radius: 5px;
border: 0px;
cursor: pointer;
}
</style>
</head>

<body>
<div class="container">
<form id="signup-form" novalidate>
<input type="text" id="username" placeholder="Enter Username" aria-describedby="username-error">
<span id="username-error" class="error-message" aria-live="polite"></span>

<input type="email" id="email" placeholder="Enter Email" aria-describedby="email-error">
<span id="email-error" class="error-message" aria-live="polite"></span>

<button type="submit">Sign Up</button>
</form>
<p id="success-message" class="success-message"></p>
</div>

<script>
document.addEventListener("DOMContentLoaded", () => {
const form = document.getElementById("signup-form");
const username = document.getElementById("username");
const email = document.getElementById("email");
const usernameError = document.getElementById("username-error");
const emailError = document.getElementById("email-error");
const successMessage = document.getElementById("success-message");

const validationRules = {
username: {
required: "Username cannot be empty!",
minLength: { value: 3, message: "Username must be at least 3 characters long!" },
maxLength: { value: 15, message: "Username cannot exceed 15 characters!" }
},
email: {
required: "Email cannot be empty!",
pattern: {
value: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
message: "Invalid email address!"
}
}
};

function validateInput(input, rules, errorElement) {
let value = input.value.trim();
let errorMessage = "";

if (!value) {
errorMessage = rules.required;
} else if (rules.minLength && value.length < rules.minLength.value) {
errorMessage = rules.minLength.message;
} else if (rules.maxLength && value.length > rules.maxLength.value) {
errorMessage = rules.maxLength.message;
} else if (rules.pattern && !rules.pattern.value.test(value)) {
errorMessage = rules.pattern.message;
}

if (errorMessage) {
showError(input, errorMessage, errorElement);
return false;
} else {
clearError(input, errorElement);
return true;
}
}

function showError(input, message, errorElement) {
errorElement.textContent = message;
input.classList.add("error");
}

function clearError(input, errorElement) {
errorElement.textContent = "";
input.classList.remove("error");
}

username.addEventListener("input", () => validateInput(username, validationRules.username, usernameError));
email.addEventListener("input", () => validateInput(email, validationRules.email, emailError));

form.addEventListener("submit", (event) => {
event.preventDefault();

let isUsernameValid = validateInput(username, validationRules.username, usernameError);
let isEmailValid = validateInput(email, validationRules.email, emailError);

if (isUsernameValid && isEmailValid) {
successMessage.textContent = "Form submitted successfully!";
form.reset();
} else {
successMessage.textContent = "";
}
});
});
</script>

</body>

</html>

πŸ”Ή Best Practice: Use trim() to remove unnecessary spaces and regular expressions (RegEx) for accurate email validation.

πŸ“Œ Project 2: Calculator

A simple calculator that performs basic arithmetic operations.

πŸ”Ή What is a JavaScript Calculator?

A JavaScript calculator allows users to enter numbers and perform arithmetic operations dynamically.

πŸ›  How It Works?

  • Users input numbers and operators.
  • JavaScript listens for button clicks.
  • The entered expression is evaluated and displayed.

πŸ“Œ Code Implementation:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculator</title>
<style>
.calculator {
width: 300px;
margin: auto;
text-align: center;
border: 2px solid #ccc;
padding: 20px;
border-radius: 10px;
background: #f9f9f9;
}

#display {
width: 100%;
font-size: 20px;
text-align: right;
margin-bottom: 10px;
padding: 10px;
box-sizing: border-box;
}

.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 5px;
}

button {
padding: 10px;
font-size: 18px;
border: none;
background: #ddd;
cursor: pointer;
}

button:hover {
background: #bbb;
}
</style>
</head>

<body>
<div class="calculator">
<input type="text" id="display" readonly>
<div class="buttons">
<button onclick="clearDisplay()">C</button>
<button onclick="appendValue('7')">7</button>
<button onclick="appendValue('8')">8</button>
<button onclick="appendValue('9')">9</button>
<button onclick="appendValue('+')">+</button>

<button onclick="appendValue('4')">4</button>
<button onclick="appendValue('5')">5</button>
<button onclick="appendValue('6')">6</button>
<button onclick="appendValue('-')">-</button>

<button onclick="appendValue('1')">1</button>
<button onclick="appendValue('2')">2</button>
<button onclick="appendValue('3')">3</button>
<button onclick="appendValue('*')">*</button>

<button onclick="appendValue('0')">0</button>
<button onclick="appendValue('.')">.</button>
<button onclick="calculateResult()">=</button>
<button onclick="appendValue('/')">/</button>
</div>
</div>

<script>
let display = document.getElementById("display");
let calculated = false; // Track if the result is already calculated

function appendValue(value) {
if (calculated) {
display.value = ""; // Reset display if new input is given after calculation
calculated = false;
}
display.value += value;
}

function calculateResult() {
try {
display.value = safeEval(display.value);
calculated = true; // Set flag after calculation
} catch (error) {
display.value = "Error";
}
}

function clearDisplay() {
display.value = "";
calculated = false;
}

// βœ… Secure Expression Evaluation Function
function safeEval(expression) {
let allowedChars = /^[0-9+\-*/(). ]+$/;
if (!allowedChars.test(expression)) {
throw new Error("Invalid Input");
}
return new Function("return " + expression)();
}
</script>
</body>

</html>

πŸ”Ή Best Practice: Ensure secure evaluation using safeEval() to prevent malicious input execution.

πŸ“Œ Project 3: FAQ Accordion (Dynamic UI Component)

An FAQ accordion expands or collapses content when clicked.

πŸ”Ή What is an Accordion UI?

An accordion UI hides/show sections dynamically when users interact with them.

πŸ›  How It Works?

  • Each FAQ section has a button.
  • Clicking the button toggles the visibility of the answer.

πŸ“Œ Code Implementation:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FAQs</title>
<style>
.container {
max-width: 700px;
background-color: gainsboro;
box-shadow: 1px 1px 5px gray;
margin: 50px auto;
padding: 25px;
}

.faq-container {
background-color: #fff;
padding: 15px;
border-radius: 5px;
margin-bottom: 15px;
font-family: Arial, Helvetica, sans-serif;
letter-spacing: 1px;
}

.faq-question {
cursor: pointer;
font-weight: 600;
}

.faq-answer {
max-height: 0;
overflow: hidden;
opacity: 0;
transition: max-height 0.3s ease-out, opacity 0.3s ease-out;

}

.show {
max-height: 100%;
opacity: 1;
margin-top: 15px;
}
</style>
</head>

<body>
<div class="container">
<div class="faq-container">
<div class="faq-question">
What is JavaScript?
</div>
<div class="faq-answer">
JavaScript is a programming language used to create interactive web applications.
</div>
</div>
<div class="faq-container">
<div class="faq-question">
What is the difference between `let`, `const`, and `var`?
</div>
<div class="faq-answer">
`let` and `const` were introduced in ES6. `var` is function-scoped, while `let` and `const` are
block-scoped. `const`
cannot be reassigned.
</div>
</div>
<div class="faq-container">
<div class="faq-question">
What is an event listener in JavaScript?
</div>
<div class="faq-answer">
An event listener is a function that waits for a specific event (like click, hover, etc.) and executes
when that event
occurs.
</div>
</div>
</div>


<script>
document.querySelectorAll('.faq-container').forEach(item => {
item.addEventListener("click", () => {
let answer = item.querySelector('.faq-answer');
answer.classList.toggle('show');

// Keep Rest Items Hide
document.querySelectorAll('.faq-answer').forEach(ans => {
if (ans !== answer) {
ans.classList.remove('show');
}
});
});
});

</script>
</body>

</html>

πŸ”Ή Best Practice: Use CSS transitions for smooth animations instead of setting display: block manually.

🎯 Conclusion

Building mini projects helps reinforce JavaScript concepts practically! πŸš€

βœ… Key Takeaways:
βœ” Form Validation β€” Ensures correct user input with real-time feedback.
βœ” Calculator β€” Performs real-time arithmetic operations.
βœ” FAQ Accordion β€” Expands/collapses UI content dynamically.

πŸš€ Try these projects and modify them to enhance your learning!

πŸ’¬ Which project did you like the most? Share your thoughts in the comments! πŸ‘‡

Sign up to discover human stories that deepen your understanding of the world.

Lokesh Prajapati
Lokesh Prajapati

Written by Lokesh Prajapati

Front-end-developer | Web Designer | Shopify Experts - https://lokesh-prajapati.vercel.app/

No responses yet

Write a response