Full Stack Camp
144 subscribers
8 photos
16 files
89 links
Fullstack Camp | Learn. Build. Launch.
Welcome to the ultimate tech adventure!
Join us for a hands-on journey through HTML, CSS, JavaScript, React, Node.js, Express & MongoDB — all in one place.
Download Telegram
6) ES6 Classes (Modern, cleaner syntax)
Now we use ES6 classes which are syntax sugar over prototypes. The behavior is the same; the code is cleaner.

6.1 Basic class with constructor and methods

class Person {
     constructor(name, age) {
         this.name = name; // instance property
        this.age = age; } // methods go on the prototype (shared)

     greet() { console.log(Hi, I'm ${this.name} and I'm ${this.age}.); } }

const p = new Person("Betelhem", 21); p.greet();


Under the hood, greet is still placed on Person.prototype.


6.2 Inheritance with extends and super
We can make a new class that inherits from another.

class Student extends Person {
      constructor(name, age, major) {
            super(name, age); // call Person constructor
            this.major = major; }  

      study() {
           console.log(
${this.name} is studying ${this.major}.); } }
const st = new Student("Samuel", 20, "Math");
st.greet(); // inherited
st.study(); // own method



6.3 Getters, setters, and static methods (handy basics)
➤setters and getters allow controlled access properties. For example , using set we can prevent the user from entering a number for names.

class BankAccount {
       constructor(owner, balance = 0) {
            this.owner = owner;
            this._balance = balance; // convention: underscore = "internal" }

// Getter (access like a property)
get balance() {
      return this._balance; }

// Setter (validate on assignment)
set balance(value) {
     if (value < 0) {
          console.log("Balance cannot be negative.");
         return; }
     this._balance = value; }

deposit(amount) {
       this._balance += amount; }

withdraw(amount) {
       if (amount > this._balance) {
            console.log("Insufficient funds!"); return; }
this._balance -= amount; }

// Static method (belongs to the class, not instances)

static compare(a, b) {
      return a.balance - b.balance; } }

const a1 = new BankAccount("Hanna", 1000);
const a2 = new BankAccount("Abel", 500);
a1.deposit(200);

console.log(a1.balance); // getter a1.balance = 50; // setter console.log(BankAccount.compare(a1, a2)); // static


getter/setter make property-style reads/writes that run code under the hood.
static methods are utilities on the class itself (not on instances).

7) this inside classes and methods (quick reminder)
➥In class methods and prototype methods, this refers to the instance that called the method.
➥Avoid using arrow functions for prototype methods when you need dynamic this. Arrow functions capture this from the outer scope, which can surprise you.

class Demo {
     constructor(name) {
        this.name = name; }

     sayName() { // good console.log(this.name); }

sayNameArrow = () => {
     // fine for fields, but
this is lexically bound console.log(this.name); } }


8) Real‑World Mini Example :Library with Books (composition + classes)

class Book {
     constructor(title, author, pages) {
        this.title = title;
        this.author = author;
        this.pages = pages;
        this.read = false; }
    markRead() {
         this.read = true; } }

class Library {
      constructor(name) {
           this.name = name;
           this.collection = []; // array of Book instances }
     addBook(book) {
          this.collection.push(book); }
      listUnread() {
           return this.collection.filter(b => !b.read); }
}
const b1 = new Book("Javascript Essentials", "Sara", 220);
const b2 = new Book("CSS Mastery", "Almaz", 180);
const lib = new Library("Addis Tech Library");
lib.addBook(b1);
lib.addBook(b2);
b1.markRead(); console.log(lib.listUnread().map(b => b.title));


9) Common Pitfalls (and fixes)
Forgetting new with constructor functions:
Defining methods inside the constructor (duplicates for each instance). Prefer prototypes or class methods.
Arrow functions as class/prototype methods when you expect dynamic this. Use regular methods unless you need lexical binding.
Forgetting to reset constructor after Object.create in old‑style inheritance:
💥💥Week 4 Day 5 — OOP Challenges

Hey Campers 👋, you’ve now entered the world of Object-Oriented Programming. Today’s challenges are all about practicing classes, objects, and inheritance.
👉 Here are 6 challenge ideas — choose any 3 that excite you most.

1. 🎓 School System Lite

➤Create a Student class with properties like name, age, and grade.
➤Add methods like study() and introduce().
➤Create a Teacher class that inherits from a Person class and has an extra method teach().
💡 Hint: Use extends to inherit, and remember to call super() inside your constructor.

2. 📒 Contact Book OOP

➤Make a Contact class with name, phone, and email.
➤Create a ContactBook class to manage many contacts.
➤Add methods like addContact(), removeContact(), and listContacts().
💡 Hint: Store contacts in an array inside ContactBook.

3. 🛒 Shopping Cart Pro

➤Create a Product class with name and price.
➤Build a Cart class to addProduct(), removeProduct(), and calculateTotal().
➤Add a price validation using getters and setters.


4. 🎬 Movie Watchlist OOP

➤Create a Movie class with title, genre, and watched.
➤Add a method toggleWatched() to switch watched status.
➤Create a Watchlist class to manage multiple movies.
💡 Hint: Add a listUnwatched() method for extra fun.

5. 🏦 ATM Simulation

➤Create a BankAccount class with owner and balance.
➤Add methods deposit(), withdraw(), and checkBalance().
➤Prevent withdrawing more than available balance.
💡 Hint: Use conditionals inside your withdraw() method.

6. 🚗 Transport System

➤Make a Vehicle class with brand and speed.
➤Add methods like drive() and stop().
➤Extend it into Car and Bus classes, each with its own style of drive().



Now it’s your turn! Choose any 3 challenges and start building.

Remember:
▶️Share your solutions 🖥️
▶️Invite friends to join the fun 👭

▶️Stay well, stay curious, and stay coding! ✌️🔥
🌟 Week 4 Day 6 — Introduction to the DOM

👋 Hello my awesome campers!

Welcome back to another exciting session. You’ve been doing amazing with JavaScript so far. Up until now, most of the things we did lived inside the console — we logged messages, built little games, tracked moods, handled functions, closures, and even dived into OOP.

But let’s be honest… if we only live in the console forever, it’s kinda boring, right? 😅

The real fun of JavaScript is making web pages alive — adding interactivity, changing text, moving things, and responding to what the user does.
👉 That’s where DOM comes in.

🏗️ What is the DOM?

DOM stands for Document Object Model.
Sounds scary? Let’s break it down:
Document → this means your HTML page.
Object Model → your browser takes that HTML and turns it into an object-like structure that JavaScript can understand.
➤Think of your web page like a family tree 🌳:
➥At the very top, you have the document (the root).
➥Inside, you have children: <html>, <head>, <body>.
➥Inside <body> you have more children: <h1>, <p>, <div>, <button>, etc.
➥And inside them, maybe even more children!

So the DOM is basically a map of your page that JavaScript can walk through and change.

🔍 Example: HTML and its DOM

<!DOCTYPE html>
<html>
<head>
     <title>My First DOM Page</title>
</head>
<body>
     <h1 id="title">Hello Campers!</h1>
    <p class="message">Welcome to the world of DOM.</p>
    <button>Click Me!</button>
</body>
</html>



Now, the DOM is how JavaScript sees this page.
The browser turns it into a tree like this:

Document
   └── html
    ├── head │
        └── title → "My First DOM Page"
    └── body
        ├── h1#title → "Hello Campers!"
        ├── p.message → "Welcome to the world of DOM."
        └── button → "Click Me!"



🛠️ Accessing the DOM with JavaScript

To work with the DOM, we use the global object document.
Think of document as the "doorway" into the HTML page.

Example 1: Select by ID

let heading = document.getElementById("title");
console.log(heading);



👉 Output: <h1 id="title">Hello Campers!</h1>

We grabbed the <h1> element from the page.

Example 2: Select by Class

let message = document.getElementsByClassName("message");
console.log(message);


👉 Output: an HTMLCollection with <p class="message">Welcome to the world of DOM.</p>

Example 3: Select by Tag Name

let buttons = document.getElementsByTagName("button");
console.log(buttons);


👉 Output: an HTMLCollection with all <button> elements.

Example 4: Modern Query Selector

let heading = document.querySelector("#title"); // first match
let paragraph = document.querySelector(".message"); // first element with class "message"

let button = document.querySelector("button"); // first <button>


And if you want all matches:

let allButtons = document.querySelectorAll("button");
console.log(allButtons);



✍️ Changing the DOM
Cool, now we don’t just want to find elements — we want to change them!

1. Change Text

let heading = document.getElementById("title");
heading.textContent = "Hello JavaScript World!";


👉 This replaces the <h1> text.

2. Change HTML Inside

paragraph.innerHTML = "<strong>DOM is powerful!</strong>";


👉 Puts bold text inside the paragraph.

3. Change Styles

heading.style.color = "blue";
heading.style.fontSize = "50px";


👉 Makes the heading big and blue.

4. Add or Remove Classes

heading.classList.add("highlight");
heading.classList.remove("highlight");
🎯 Real Life Example
Imagine you have a scoreboard in a game:

<h2 id="score">Score: 0</h2>
<button id="increase">Increase</button>


JavaScript can make it dynamic:

let score = 0;
let scoreBoard = document.getElementById("score");
let btn = document.getElementById("increase");

btn.addEventListener("click", function() {
      score += 1;
      scoreBoard.textContent = "Score: " + score; });


Now every time the button is clicked → score goes up. 🎉

🤔 Why is DOM Important?
Without DOM:
➤Your page would just sit there, lifeless 🪦.
With DOM:
➤You can create games, interactive forms, todo lists, dynamic shopping carts, quizzes, and basically any modern website feature.

DOM = JavaScript + HTML + CSS working together.

🌟 Wrap Up
Today we learned:
DOM = Document Object Model (a tree of your page).
document object lets JS access and control HTML.
Ways to select elements: ➥getElementById, ➥getElementsByClassName, ➥getElementsByTagName, ➥querySelector, querySelectorAll.
Ways to change DOM: textContent, innerHTML, style, classList.
Why DOM makes web pages interactive.
We’ll dive deeper into events and more DOM manipulation tricks in the coming days.
💥💥 Week 4 Day 6 — DOM Challenges

Choose any 3 of the following:

1. 🏫 Student Roster Formatter

You’re given a list of student names inside <ul>.
Task: Loop through all <li> items and make them uppercase.
Hint: Use getElementsByTagName or querySelectorAll and a for loop.

2. 📚 Quote of the Day

Have an empty <p id="quote"> on your page.
Task: Store 5 quotes in an array. Select one at random and display it in the <p>.
Hint: Use Math.random() and .textContent.

3. 🎨 Rainbow Paragraphs

You have several <p> elements on the page.
Task: Give each one a different color from an array of colors (["red", "orange", "green", "blue", "purple"]).
Hint: Loop and use .style.color.

4. 🎭 Identity Switcher

Suppose your page has <h1 id="title">Welcome</h1> and <p id="desc">This is a page</p>.
Task: Swap their contents (the <h1> text becomes the <p> text and vice versa).

5. 🌍 Language Translator Lite

You have <p id="greet">Hello</p>.
Task: Create an array of greetings (["Hola", "Bonjour", "Ciao", "Hallo"]) and make the <p> cycle through them one by one when the script runs.

Wrap Up
👉 Choose any 3 challenges.
👉 Use everything you’ve learned so far: loops, arrays, objects, and DOM properties (.textContent, .style, etc.).

👉 And as always:
     share,
    invite,
    stay curious, and stay coding ✌️
🌞 Week 4 — Day 7: DOM Events & Dynamic Elements (Deep deep Dive!)

Hey amazing campers 👋😄

You’ve met the DOM and learned how to select elements and change them. Today we’ll make pages come alive with events (clicks, typing, submitting, mouse moves…) and learn how to create, insert, and remove elements with JavaScript. This is the moment JS starts to feel magical.

0) Quick mental model: what’s an “event”?
An event is something that happens in (or to) the page: a button is clicked, a user types in a field, a form is submitted, an image finishes loading, etc.

We can listen for that event and then run code in response. That’s interactivity.
1) Two ways to listen for events

A) The old way (inline or property)
Inline in HTML (not recommended):

<button onclick="alert('Clicked!')">Click me</button>


Property on element (okay for quick demos):

const btn = document.getElementById('myBtn'); btn.onclick = function () { console.log('Clicked!'); };

Limitation: Only one onclick can exist at a time; assigning a new one overwrites the old.

B) The modern way (recommended): addEventListener

const btn = document.getElementById('myBtn');
function handleClick() {
      console.log('Clicked!'); }

btn.addEventListener('click', handleClick);


You can attach multiple listeners, remove them later, and choose options (like capture/once/passive).

To remove a listener, you need the same function reference:

btn.removeEventListener('click', handleClick);


2) The event object (event / e)
When an event happens, the browser gives you an event object with details about it.

document.addEventListener('click', function (e) {
     console.log('Type:', e.type); // "click"
     console.log('Target:', e.target); // the element that was clicked
      console.log('Coordinates:', e.clientX, e.clientY); });

3) Common, super-useful events
A) click

<button id="likeBtn">👍 Like</button>
<p id="count">0</p>
<script>
const likeBtn = document.getElementById('likeBtn');
const out = document.getElementById('count');
let likes = 0;
likeBtn.addEventListener('click', () => {
      likes += 1;
     out.textContent = likes; });
</script>


B) input vs change (text fields, selects)

input fires on every keystroke (live updates).
change fires when the element loses focus or the selection finalizes.

<input id="nameField" placeholder="Type your name..." />
<p id="preview"></p>
<script>
const nameField = document.getElementById('nameField');
const preview = document.getElementById('preview');
nameField.addEventListener('input', () => {
    preview.textContent =
Hello, ${nameField.value || 'stranger'}!; });
</script>


C) submit (forms) + preventing reload
Forms submit by default (page reload). Stop that with event.preventDefault().

<form id="loginForm">
<input name="user" placeholder="Username" required />
<input name="pass" type="password" placeholder="Password" required />
<button>Log in</button>
</form>
<p id="msg"></p>
<script> const form = document.getElementById('loginForm');
const msg = document.getElementById('msg');
form.addEventListener('submit', (e) => {
     e.preventDefault(); // stop page reload
const user = form.user.value;
const pass = form.pass.value;
msg.textContent =
Trying to log in as: ${user} (password length: ${pass.length}); });
</script>


D) Keyboard events: keydown, keyup

<input id="command" placeholder="Type then press Enter" />
<p id="result"></p>
<script>
const command = document.getElementById('command');
const result = document.getElementById('result');
command.addEventListener('keydown', (e) => {
   if (e.key === 'Enter') { result.textContent =
You entered: ${command.value}; } });
</script>


E) Mouse events: mouseover / mouseout / mousemove

<div id="box" style="width:200px;height:120px;background:#eef;border:1px solid #99f;">
</div>
<p id="coord"></p>
<script>
const box = document.getElementById('box');
const coord = document.getElementById('coord');
box.addEventListener('mousemove', (e) => {
coord.textContent =
x: ${e.offsetX}, y: ${e.offsetY}; });
</script>
F) Focus events: focus / blur

<input id="email" placeholder="Email" />
<p id="hint"></p>
<script>
const email = document.getElementById('email');
const hint = document.getElementById('hint');
email.addEventListener('focus', () => hint.textContent = 'Format: name@example.com');
email.addEventListener('blur', () => hint.textContent = '');
</script>


4) Event Bubbling, Capturing & Delegation (beginner-friendly)
Bubbling & Capturing (just enough to use)

When you click a child element, the event travels:
Capturing: from document → down to the target.
Bubbling: from the target → back up to document (this is the default most people use).
➤addEventListener(type, handler, options):
➤{ capture: true } makes the handler run on the capturing phase.
➤{ once: true } runs the handler only once.
➤{ passive: true } tells the browser the handler won’t call preventDefault() (useful for scroll).

Event Delegation (powerful & simple)
Attach one listener to a parent and handle many children based on e.target.

<ul id="menu">
<li data-action="home">Home</li>
<li data-action="about">About</li>
<li data-action="contact">Contact</li>
</ul>
<p id="out"></p>
<script>
const menu = document.getElementById('menu');
const out = document.getElementById('out');
menu.addEventListener('click', (e) => {
    if (e.target.matches('li')) {
    const action = e.target.dataset.action; // from data-action
    out.textContent =
You clicked: ${action}; } });
</script>


Works even if you later add more <li>s—one listener handles all.

5) Creating & inserting elements (the dynamic DOM)
A) createElement, set content/attrs, then insert

<ul id="todos"></ul>
<script>
const todos = document.getElementById('todos');
const li = document.createElement('li');
li.textContent = 'Learn DOM';
li.setAttribute('data-priority', 'high');
todos.appendChild(li); // insert as last child
</script>


B) append, prepend, before, after, insertBefore

<div id="wrap">
<p>First</p>
</div>
<script>
const wrap = document.getElementById('wrap');
const p1 = document.createElement('p');
p1.textContent = 'Appended at end';
wrap.append(p1);
const p2 = document.createElement('p');
p2.textContent = 'Prepended at start';
wrap.prepend(p2);
const outsideTop = document.createElement('p');
outsideTop.textContent = 'Before the wrapper';
wrap.before(outsideTop);
const outsideBottom = document.createElement('p');
outsideBottom.textContent = 'After the wrapper';
wrap.after(outsideBottom);
</script>


C) Removing elements: element.remove() or parent.removeChild(child)

const item = document.querySelector('#todos li');
item.remove(); // easy way
// or old-school:
const parent = document.getElementById('todos');
const first = parent.firstElementChild;
parent.removeChild(first);


D) Cloning nodes: cloneNode

const original = document.querySelector('#todos li');
const copy = original.cloneNode(true); // true = deep clone (children too)
original.after(copy);


E) innerHTML vs textContent (safety & speed)
➤textContent → sets text only (safe; shows <b> as text).
➤innerHTML → parses as HTML (powerful, but never put untrusted user input here—XSS risk).

const box = document.getElementById('box');
box.textContent = '<b>hello</b>'; // shows literally <b>hello</b>
box.innerHTML = '<b>hello</b>'; // renders bold hello


6) Managing classes & styles cleanly
A) classList

const card = document.getElementById('card');
card.classList.add('active');
card.classList.remove('hidden');
card.classList.toggle('highlight'); // add if missing, remove if present
const hasIt = card.classList.contains('active');

B) Inline styles vs CSS classes
Prefer toggling classes (cleaner). Inline styles are fine for quick demos:

card.style.backgroundColor = 'lightyellow';
card.style.border = '1px solid #ccc';


7) Attributes, properties, and dataset
A) getAttribute / setAttribute

const link = document.querySelector('a');
link.setAttribute('href', 'https://example.com');
console.log(link.getAttribute('href'));


B) Properties (often nicer)

const img = document.querySelector('img');
img.src = 'cat.jpg';
img.alt = 'A cute cat';

C) Custom data: data-* + dataset

<button id="pay" data-plan="pro" data-price="299">Buy</button>
<script>
const pay = document.getElementById('pay');
console.log(pay.dataset.plan); // "pro"
console.log(pay.dataset.price); // "299"
</script>


8) Forms + validation basics (DOM side)

<form id="signup">
<input id="email" type="email" placeholder="Email" required />
<input id="pwd" type="password" placeholder="Password (min 6)" minlength="6" required />
<button>Sign Up</button>
</form>
<p id="status"></p>
<script>
const form = document.getElementById('signup');
const status = document.getElementById('status');
form.addEventListener('submit', (e) => {
   e.preventDefault(); if (!form.checkValidity()) {
status.textContent = 'Please fix form errors.'; return; }
const email = document.getElementById('email').value;
status.textContent =
Welcome, ${email}!; });
</script>


Uses built-in HTML validation + DOM for feedback.

9) When should your JS run? (DOMContentLoaded, defer)

Option A: Put <script> at the end of <body>
HTML loads first → then script runs (elements exist).

Option B: Use defer in the head
<script src="app.js" defer></script>
defer waits until HTML is parsed, then runs script.

Option C: Listen for the DOM to be ready

document.addEventListener('DOMContentLoaded', () => {
   // safe to query and manipulate the DOM here });


10) Mini build (step-by-step): Add items to a list + remove items
(Just a teaching demo; not a “challenge”)

<form id="todoForm">
<input id="todoInput" placeholder="New task..." />
<button>Add</button>
</form>
<ul id="todoList"></ul>
<script>
const form = document.getElementById('todoForm');
const input = document.getElementById('todoInput');
const list = document.getElementById('todoList');
form.addEventListener('submit', (e) => {
    e.preventDefault();
    const text = input.value.trim();
   if (!text) return; // 1) create
   const li = document.createElement('li');
   li.textContent = text + ' ';
// remove button
const removeBtn = document.createElement('button');
removeBtn.textContent = ''; removeBtn.setAttribute('aria-label', 'Remove item');
li.append(removeBtn);
// 2) insert
list.appendChild(li);
// 3) clear input
input.value = ''; });
// Event delegation to remove items
list.addEventListener('click', (e) => {
    if (e.target.tagName === 'BUTTON') {
  e.target.parentElement.remove(); } });
</script>


What you practiced here:
➤submit + preventDefault()
➤createElement / appendChild / append
➤event.target and delegation on the <ul>

11) Good habits & small gotchas
Prefer addEventListener over inline events.
Use textContent for text; innerHTML only when you must render HTML (never with untrusted input).
Prefer classes (classList) over inline styles.
Use defer or run code after DOMContentLoaded.
When attaching many handlers to many children, prefer event delegation on their parent.
Keep HTML semantic & accessible (use <button> for clickables, connect <label> with for to inputs, etc.).

🧠 Today you learned
The right way to handle events with addEventListener (and how to remove them).
The event object and how to use event.target.
The difference between input / change / submit / keyboard & mouse events.
Creating, inserting, cloning, and removing elements.
classList, attributes vs properties, and custom data- attributes.
How to organize scripts so the DOM exists when your code runs.


🔥🔥You just unlocked the power to build real interactive pages. 🚀
🌟 Week 4 Day 7 Challenges 🌟

Hello my dear campers 🙌,
You’ve done amazing learning DOM events, onclick, createElement, and appendChild.
Now it’s time to practice with fun challenges that will push your creativity.

Pick any 3 challenges from the list below 👇

1. Click Counters for Like & Dislike Buttons 👍👎

What to do:
➤Create two buttons: "Like" and "Dislike".
➤Each button should count how many times it’s clicked and display the number.
💡Hint:
➥Use let likeCount = 0 and let dislikeCount = 0.
➥Update the text using textContent when a button is clicked.

2. Dynamic Color Changer 🎨

What to do:
➤Make a button that changes the background color of the page every time it’s clicked.
💡Hint:
➥Store a list of colors in an array like ["red", "blue", "green"].
➥On click, randomly pick a color and apply it with document.body.style.backgroundColor.

3. Task List Maker 📝

What to do:
➤Let the user type a task in an input box and add it as a list item when clicking “Add”.
💡Hint:
➥Use document.createElement("li") and appendChild to add new tasks into a <ul>.
➥Don’t forget to grab the input value with .value.

4. Image Switcher 🖼️

What to do:
➤Display an image and a button. When the button is clicked, the image changes.
💡Hint:
➥Use an array of image URLs.
➥Swap the src attribute of the <img> when the button is clicked.

5. Emoji Rain 🌸🍕😂

What to do:
➤Have a button that, when clicked, drops a new emoji onto the page.
💡Hint:
➥Use document.createElement("span").
➥Set its textContent to an emoji.
➥Append it to the body each time the button is clicked.

Choose any 3 challenges, try them out, and have fun!

Don’t forget to
💥💥 share your solutions,
💥💥invite your friends,
and as always…

💥💥✌️✌️stay well, stay curious, and stay coding ✌️
🌟 Week 4 Day 7 (Continued) — More DOM Practice with Examples

Hello Campers 👋,
Yesterday’s DOM session was a long ride, I know 😅. So today, instead of introducing new concepts, we’re going to strengthen what we learned through real-world, practical examples. Think of this as polishing the tools we got yesterday before moving forward.

1️⃣ Form Input Example — Username Display

Imagine you’re creating a website where someone types their username, and it appears immediately on the page.

<input type="text" id="usernameInput" placeholder="Enter your username" />
<p>Your username: <span id="displayUsername"></span></p>

<script>
  const input = document.getElementById("usernameInput");
  const display = document.getElementById("displayUsername");

  input.addEventListener("input", function () {
    display.textContent = input.value;
  });
</script>


🔎 Explanation:
➤input.addEventListener("input", ...) listens for typing.
➤Whatever you type is instantly shown inside the <span> → like live preview.
➤Real world use: think of Instagram showing your chosen username in real time.

2️⃣ 🎨 Button Example — Dark Mode Toggle

Most websites today have light mode / dark mode. Let’s simulate that.

<button id="toggleBtn">Switch to Dark Mode</button>

<script>
  const button = document.getElementById("toggleBtn");

  button.addEventListener("click", function () {
    document.body.classList.toggle("dark");
    if (document.body.classList.contains("dark")) {
      button.textContent = "Switch to Light Mode";
    } else {
      button.textContent = "Switch to Dark Mode";
    }
  });
</script>
<style>
  body.dark {
    background-color: black;
    color: white;
  }
</style>


🔎 Explanation:
➤We add/remove a class .dark using classList.toggle().
➤Button text also changes depending on the mode.
➤Real world use: exactly like YouTube or Twitter’s dark mode button.

3️⃣ 📝 Character Counter Example

You know when you type a tweet and it says “150 characters left”? Let’s build that.

<textarea id="tweetInput" rows="3" cols="30" maxlength="150"></textarea>
<p>Characters left: <span id="counter">150</span></p>

<script>
  const textarea = document.getElementById("tweetInput");
  const counter = document.getElementById("counter");
  const max = 150;

  textarea.addEventListener("input", function () {
    let remaining = max - textarea.value.length;
    counter.textContent = remaining;
  });
</script>


🔎 Explanation:
➤maxlength="150" restricts typing beyond 150 characters.
➤Every keystroke updates the counter.
➤Real world use: Twitter, Facebook, or SMS apps do this.

4️⃣ 🎵 Image Hover Example — Album Preview

When you hover over an album cover, the picture changes (like previewing a music album or movie poster).

<img id="album" src="cover1.jpg" width="200">

<script>
  const album = document.getElementById("album");

  album.addEventListener("mouseover", function () {
    album.src = "cover2.jpg";
  });

  album.addEventListener("mouseout", function () {
    album.src = "cover1.jpg";
  });
</script>


🔎 Explanation:
➤mouseover changes the image.
➤mouseout resets it back.
➤Real world use: online stores showing product preview images when you hover.
5️⃣ 🔍 Live Search Filter (Search While Typing)

Think about when you search for a contact or product and the list filters as you type.

<input type="text" id="searchInput" placeholder="Search names..." />
<ul id="namesList">
    <li>Alem</li>
    <li>Berihu</li>
    <li>Chaltu</li>
    <li>Dawit</li>
   <li>Megersa</li>
</ul>

<script>
const input = document.getElementById("searchInput");
const list = document.getElementById("namesList").getElementsByTagName("li");

input.addEventListener("input", function () {
     const filter = input.value.toLowerCase();
     for (let i = 0; i < list.length; i++) {
       let name = list[i].textContent.toLowerCase();
      if (name.includes(filter)) {
            list[i].style.display = ""; }
      else { list[i].style.display = "none"; } }
});
</script>


🔎 Explanation:
➤Every time you type, the list is scanned.
➤Only names that include the typed letters stay visible.
➤Real world: search boxes in contacts apps, e-commerce, or file managers.

6️⃣ 📑 Tab Navigation (Switch Sections Without Reloading)

Websites often have tabs (e.g., Profile | Settings | Notifications).

<button onclick="showTab('profile')">Profile</button>
<button onclick="showTab('settings')">Settings</button>
<div id="profile" class="tab">Welcome to your profile!</div>
<div id="settings" class="tab" style="display:none;">Here are your settings.</div>
<script>
function showTab(tabId) {
     const tabs = document.getElementsByClassName("tab");
for (let i = 0; i < tabs.length; i++) {
     tabs[i].style.display = "none"; }
document.getElementById(tabId).style.display = "block"; }
</script>


🔎 Explanation:
➤All tabs are hidden at first.
➤Clicking a button reveals the right one.
➤Real world: Gmail or Facebook using tabs inside profile/settings sections.

7️⃣ 📂 Accordion (Open/Close Sections Like FAQs)

You’ve seen websites where FAQs expand when clicked.

<button class="accordion">What is JavaScript?</button>
<div class="panel">JavaScript is a programming language for the web.</div>
<button class="accordion">What is DOM?</button>
<div class="panel">DOM lets JavaScript interact with web pages.</div>

<script>
const acc = document.getElementsByClassName("accordion");
for (let i = 0; i < acc.length; i++) {
     acc[i].addEventListener("click", function () {
         const panel = this.nextElementSibling;
         panel.style.display = panel.style.display === "block" ? "none" : "block"; });
}
</script>
<style>
.panel {
     display: none;
     padding: 5px;
     background: #f1f1f1;
      margin-bottom: 5px; }
</style>


🔎 Explanation:
➤Each button toggles the next section (nextElementSibling).
➤FAQ answers expand/collapse when clicked.
➤Real world: FAQ pages, product descriptions, app menus.

That makes 7 practical DOM examples now, all taken from real websites you use daily.

👉 Tomorrow, we’ll move forward with new concepts. For today, make sure you retype these examples, play with them, and even modify them to fit your own creative ideas.

Stay curious, stay coding and Stay well 🥰✌️
🌞 Week 4 Day 8 — Forms & Validation in JavaScript

👋 Hello Campers!
I hope you’re doing great. We’ve gone through variables, functions, OOP, DOM, and events… and now it’s time to get into something very real-world: Forms & Validation.
Everywhere you go online — Facebook login, Google signup, online shopping checkout — you’re filling out forms. Without forms, websites are just pretty pages with no way to interact with users.
Today, we’ll dive deep into:
➤What forms are and how to grab their data with JavaScript.
➤Validating input (checking if it’s empty, long enough, or matches a rule).
➤Giving feedback to the user (error messages, colors, etc).
Let’s go step by step.

📝 1. Forms in HTML
A simple form looks like this:

<form id="signupForm">
   <label>Username:</label>
  <input type="text" id="username" /> <br><br>
   <label>Password:</label>
   <input type="password" id="password" /> <br><br>
  <button type="submit">Sign Up</button>
</form>


👉 Notice:
➥<form> wraps everything.
➥Inputs (text, password, email, etc.) are where users type.
➥A button with type="submit" tries to send the form.
🎯 2. Accessing Form Data with JS
We need JavaScript to “catch” the values typed.

const form = document.getElementById("signupForm");
form.addEventListener("submit", function(event) {
      event.preventDefault(); // stops the form from reloading the page
      const username = document.getElementById("username").value;
    const password = document.getElementById("password").value;
console.log("Username:", username);
console.log("Password:", password); });


Explanation:
➥event.preventDefault() is super important! By default, forms reload the page when submitted. This stops that.
➥.value gets whatever the user typed.
🚦 3. Basic Validation
Validation means checking: Is the input good enough?
Example: Require a username and a password of at least 6 characters.

form.addEventListener("submit", function(event) {
   event.preventDefault();
   const username = document.getElementById("username").value.trim();
   const password = document.getElementById("password").value;
    if (username === "") {
            alert("Username cannot be empty!"); return; }
  if (password.length < 6) {
            alert("Password must be at least 6 characters long!"); return; }
alert("Form submitted successfully 🎉"); });


💡 Tips:
➥.trim() removes spaces at start/end.
➥We use simple if statements to validate.
4. Real-World Example — Email Validation
Almost every form has an email field.

<form id="emailForm">
    <input type="email" id="email" placeholder="Enter your email">
    <button type="submit">Subscribe</button>
</form>



const emailForm = document.getElementById("emailForm"); emailForm.addEventListener("submit", function(event) {
     event.preventDefault();
     const email = document.getElementById("email").value;
      if (!email.includes("@") || !email.includes(".")) {
       alert("Please enter a valid email!");
return; }
alert("Subscribed successfully "); });


🎨 5. Better User Feedback
Instead of only alert(), we can show errors below inputs:

<form id="loginForm">
  <input type="text" id="user" placeholder="Username">
  <p id="userError" style="color:red"></p>
<input type="password" id="pass" placeholder="Password">
<p id="passError" style="color:red"></p>
<button type="submit">Login</button>
</form>



const loginForm = document.getElementById("loginForm");
loginForm.addEventListener("submit", function(event) {
    event.preventDefault();
    const user = document.getElementById("user").value.trim();
     const pass = document.getElementById("pass").value;
   const userError = document.getElementById("userError");
   const passError = document.getElementById("passError"); // Clear old errors
userError.textContent = "";
passError.textContent = "";
if (user === "") {
   userError.textContent = "Username required!"; return; }
if (pass.length < 6) {
     passError.textContent = "Password too short!"; return; }
alert("Logged in 🎉"); });


👉 Now errors appear directly below the inputs instead of annoying popups.
🏗️ 6. Real-World Analogy
Think of form validation like an airport security check ✈️:
➤If you bring a passport that’s expired → blocked (invalid input).
➤If your bag is too heavy → blocked (input doesn’t meet rules).
➤If everything checks out → you can board the plane (form submits).
➤Without validation, anyone could walk in with anything (hackers, bots, nonsense data).

🔑 7. Key Points to Remember

➤Forms collect user data.
➤.value gets the input.
➤Use .trim() to remove extra spaces.
➤Always use event.preventDefault() to stop page reloads.
➤Validate inputs before submitting (length, empty, special format).
➤Give user-friendly feedback (errors under inputs).
🌟 Week 4 Day 8 Challenge: Ultimate Signup Form
👋 Hey Campers, hope you’re doing great! Today’s challenge is a big one 🎉. You’re going to build a Signup Form with validations + styling so it looks and feels like a real app.

What to Do
Build a form with these fields:
Username
➤Cannot be empty.
➤At least 3 characters long.
➤No spaces allowed.
Email
➤Must have "@" and ".".
➤Show error if invalid.
Password & Confirm Password
➤Password must be at least 6 characters.
➤Confirm password must match.
Age
➤Must be 18 or older.
Phone Number
➤Must be exactly 10 digits.
Message / Bio
➤Optional, but if filled → at least 10 characters.

👉 Show error messages under each field.
👉 If everything is valid → display a big “Signup Successful!”.

🎨 Don’t Forget CSS!
Make it look nice:
➤Add some colors (green for success, red for errors).
➤Use margins and padding to space out inputs.
➤Add a hover effect to the submit button.
➤Maybe even round the corners with border-radius.

💡 Hints
➤Use .value.trim() to ignore empty spaces.
➤Use includes("@") and includes(".") for email checks.
➤Compare passwords with ===.
➤Use Number(age) for numeric checks.
➤Add/remove CSS classes like "error" or "success" to style feedback.

📢 Campers:
“This one is like building a real signup page 🌍. Make it functional and stylish. Share your creations, invite others to join the journey, and as always — stay well, stay curious, and stay coding ✌️.