BCA Student Stories & UpdatesLive
DOM Events: addEventListener, Click, Input & Form Submission with preventDefault
Web applications are event-driven. An event is a signal that something has happened—a button click, a key press, or a form submission. Event listeners listen silently for these user actions and trigger handler functions in response.
Day 29 Step-by-Step Practical Flow
🎯1. What You Will Learn Today
DOM Events: addEventListener, Click, Input & Form Submission with preventDefault — Comprehensive Practical Guide
Har concept ko visual mental models, code anatomy aur practical industry tips ke sath samjhein.
Web applications are event-driven. An event is a signal that something has happened—a button click, a key press, or a form submission. Event listeners listen silently for these user actions and trigger handler functions in response.
"Think of an event listener like a doorbell chime receiver: it sits quietly waiting for someone to press the physical button (event), and the moment the button is pressed, it rings the indoor chime (handler function)."
👨🏫3. Teacher Demonstration Code
See how addEventListener handles button clicks and tracks character input in real time.
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; padding: 20px; }
.btn { padding: 8px 16px; background: #2563eb; color: #fff; border: none; border-radius: 4px; cursor: pointer; }
</style>
</head>
<body>
<h3>Interactive Counter</h3>
<button id="counter-btn" class="btn">Clicks: <span id="count">0</span></button>
<h3 style="margin-top: 24px;">Live Feedback Input</h3>
<input type="text" id="feedback-input" placeholder="Type a message..." style="padding: 8px; width: 260px;" />
<p>Character count: <span id="char-count">0</span></p>
<script>
let clicks = 0;
const btn = document.querySelector("#counter-btn");
const countDisplay = document.querySelector("#count");
btn.addEventListener("click", () => {
clicks++;
countDisplay.textContent = clicks;
});
const input = document.querySelector("#feedback-input");
const charDisplay = document.querySelector("#char-count");
input.addEventListener("input", (e) => {
charDisplay.textContent = e.target.value.length;
});
</script>
</body>
</html>2. Hands-On Practical Lab: Follow Instructions in VS Code
Code like a professional software engineer! Follow the step-by-step instructions below in Visual Studio Code (VS Code) on your PC, test your output locally, and push to GitHub.
Day 29 Practical Task Test Studio
Add a submit event listener to form that accepts event e and executes e.preventDefault().
Inside the submit handler, set confirmation.textContent = "Registration Successful!" and confirmation.style.display = "block".
Spot the Bug: Calling Function Immediately Instead of Passing Reference
Tap or click on the exact line below that contains the error:
Click any code linefunction handleButtonClick() { console.log("Button clicked!");} const btn = document.querySelector("#my-btn");// Bug: Calling the function with () inside addEventListener!btn.addEventListener("click", handleButtonClick());Senior Developer Forensic Analysis:
Passing handleButtonClick() with parentheses invokes the function immediately when the line is parsed, passing its return value (undefined) to addEventListener instead of passing the function reference.
📝Independent Practice: Assignment
📄 note-taker.htmlInteractive Live Note Taker with Character Count
- •Create day-29/index.html with a form containing a textarea and submit button.
- •Add an "input" event listener displaying real-time character count (e.g. 42 / 200).
- •Change character counter color to red if character count exceeds 180.
- •Add a submit listener that appends the note as a new paragraph element in the DOM.
Open Visual Studio Code on your PC (code .), create note-taker.html, paste this complete step-by-step verified code, test in your browser, and push to your GitHub repo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BCA Day 29 - Interactive Live Note Taker</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: 'Segoe UI', Tahoma, sans-serif;
background: #0b1120;
color: white;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.note-app {
background: #1e293b;
border: 1px solid #334155;
border-radius: 16px;
padding: 28px;
max-width: 480px;
width: 100%;
}
h1 { font-size: 20px; color: #38bdf8; margin-bottom: 16px; }
textarea {
width: 100%;
height: 100px;
background: #0f172a;
border: 1px solid #334155;
border-radius: 8px;
padding: 12px;
color: white;
font-family: inherit;
font-size: 13px;
resize: vertical;
outline: none;
}
textarea:focus { border-color: #2563eb; }
.counter-row {
display: flex;
justify-content: space-between;
align-items: center;
margin: 8px 0 16px;
font-size: 12px;
color: #94a3b8;
}
.warning { color: #ef4444; font-weight: bold; }
.btn-submit {
width: 100%;
padding: 10px;
background: #2563eb;
border: none;
border-radius: 8px;
color: white;
font-weight: bold;
cursor: pointer;
}
.notes-list { margin-top: 24px; list-style: none; }
.note-item {
background: #0f172a;
border-left: 3px solid #10b981;
padding: 10px 14px;
border-radius: 6px;
margin-bottom: 8px;
font-size: 13px;
}
</style>
</head>
<body>
<div class="note-app">
<h1>BCA Quick Lab Note Taker</h1>
<form id="noteForm">
<textarea id="noteInput" maxlength="200" placeholder="Type quick lab notes (max 200 chars)..."></textarea>
<div class="counter-row">
<span>Character Count:</span>
<span id="charCount">0 / 200</span>
</div>
<button type="submit" class="btn-submit">Add Note</button>
</form>
<ul class="notes-list" id="notesList"></ul>
</div>
<script>
const form = document.getElementById("noteForm");
const textarea = document.getElementById("noteInput");
const charCount = document.getElementById("charCount");
const notesList = document.getElementById("notesList");
// 1. Input Event: Real-time character counter
textarea.addEventListener("input", () => {
const currentLength = textarea.value.length;
charCount.textContent = `${currentLength} / 200`;
// Color red if exceeds 180 characters
if (currentLength >= 180) {
charCount.classList.add("warning");
} else {
charCount.classList.remove("warning");
}
});
// 2. Form Submit Event with e.preventDefault()
form.addEventListener("submit", (e) => {
e.preventDefault();
const text = textarea.value.trim();
if (!text) return;
// Append new note item to DOM
const li = document.createElement("li");
li.className = "note-item";
li.textContent = text;
notesList.prepend(li);
// Reset
textarea.value = "";
charCount.textContent = "0 / 200";
charCount.classList.remove("warning");
});
</script>
</body>
</html>🎓4. Viva Check: Mandatory Conceptual Test
What is the purpose of calling event.preventDefault() inside a form submit event handler?
5. Mandatory Step: Push to GitHub to Unlock Next Lesson
Target Repo: html-css-projects
Exact GitHub Setup Guide & Expected Structure
Day 29 RequirementsFollow these exact folder and file names to prevent verification errors.
index.html: Avoid spaces or custom names like Alan Turing..html or Index.HTML. Linux/GitHub servers are strictly case-sensitive.day-29/ for today so you don't overwrite previous days.main.You are welcome to read all notes, inspect code snippets, and practice all exercises of Day 29 freely! To officially submit your GitHub repository and unlock subsequent days in your portfolio, please complete Day 28: DOM Selection: querySelector, textContent, innerHTML & Dynamic Styles first.
Complete Day 28 First