🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
🕵️ SicherheitslückenBurn Out, Or Fade Away(14.09.2026 um 14:25 Uhr)
⚠️ Malware / Trojaner / VirenWindows 11 just dropped the tool ransomware abused, Microsoft says don’t restore WMIC(10.09.2026 um 20:11 Uhr)
⚠️ Malware / Trojaner / VirenWindows 11: Microsoft entfernt WMIC-Tool gegen Ransomware - ad-hoc-news.de(14.09.2026 um 07:58 Uhr)
🕵️ SicherheitslückenMicrosoft schließt Rekordzahl an Sicherheitslücken - techbook(14.09.2026 um 09:00 Uhr)
🪟 Windows TippsThe Gemini desktop app is now available for Windows(11.09.2026 um 17:06 Uhr)
🕵️ SicherheitslückenBurn Out, Or Fade Away(14.09.2026 um 14:25 Uhr)
⚠️ Malware / Trojaner / VirenWindows 11 just dropped the tool ransomware abused, Microsoft says don’t restore WMIC(10.09.2026 um 20:11 Uhr)
⚠️ Malware / Trojaner / VirenWindows 11: Microsoft entfernt WMIC-Tool gegen Ransomware - ad-hoc-news.de(14.09.2026 um 07:58 Uhr)
🕵️ SicherheitslückenMicrosoft schließt Rekordzahl an Sicherheitslücken - techbook(14.09.2026 um 09:00 Uhr)

🔧 Programmierung 🕛 vor 3 Monaten 7 Min Lesezeit
0

The FDD for Vanilla JS: The 20-Min Doc That Saves 2 Days of Rework

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Functional Design Docs aren’t corporate overhead. They are a best practice that keeps code lean.



We avoid documentation because "vanilla JS" sounds pure and self-documenting. Then we ship three versions of the same bulk-delete feature and call it "agile."



A Functional Design Document (FDD) explains how a feature gap will be implemented. It converts high-level user needs into a structured functional solution. You need this when your project has more than one developer—or when it takes more than one week of work.









1. Why This Exists
















✅ With FDD ❌ Without FDD
An FDD explains HOW a feature gap will be implemented. It converts user stories into a structured functional solution everyone agrees on before coding starts. Lack of structured design leads to confusion, incorrect assumptions, late-stage rework, and "wait, I thought we decided..." debates during code reviews.



Vanilla JS translation: Before you touch app.js, write down what the DOM can’t do yet versus what the user actually needs.










2. The Flow That Prevents Rework






CODE
Business Need ➔ Fit-Gap Analysis ➔ GAP Identified ➔ FDD Creation

Final Solution ◀─── Testing ◀─── Technical Development ◀──┘









Example: Bulk Delete Feature





  1. Business Need: "Admins need to bulk delete items."


  2. Fit-Gap: We only have single-item deletion. There are no checkboxes or mass-selection elements in the UI. (GAP Identified)


  3. FDD Creation: Write the contract first. It takes 20 minutes.


  4. Technical Development: Write the Vanilla JS (implemented below).


  5. Testing: Run validation checks against the FDD specs.


  6. Final Solution: Ships once. No surprise pull request (PR) comments.









3. The 4 Design Docs You Actually Need

































Doc Type Focus Example

FDD (Functional Design)

What it does functionally.
"Clicking 'Delete Selected' removes checked rows and shows a success toast."

TDD (Technical Design)

How the code achieves it.
Event delegation, DOM manipulation patterns, memory leak prevention.

IDD (Integration Design)
API contracts & payloads.
DELETE /api/items expects { ids: number[] }

ADD (Analytics Design)
What metrics we track. Fire bulk_delete_completed event with metadata on success.



Best Practice: Product managers own the FDD. Developers own the TDD. Both parties sign off on both documents. That is the pattern.










4. FDD Structure + The Actual Vanilla JS



Here is an FDD for a bulk delete feature, paired with the exact Vanilla JS code that satisfies its requirements.






FDD Specification





  • GAP: No way to delete multiple table rows simultaneously. The current UI restricts deletion to individual items.


  • Solution Overview: Add a checkbox column to the admin table. The header checkbox toggles all selectable rows. A sticky actions bar shows the current selection count and the delete action.


  • Business Logic:


    • Skip rows with data-status="locked".

    • Display a confirmation prompt before executing deletion.

    • Show a success toast notification and fire an analytics event on successful deletion.











The Implementation






CODE
// admin-table.js - No frameworks, just a clear contract
class BulkDeleteController {
constructor(tableSelector) {
this.table = document.querySelector(tableSelector);
this.selectedIds = new Set();
this.deleteBtn = document.querySelector('#bulk-delete-btn');
this.countEl = document.querySelector('#selected-count');

if (!this.table) return;
this.bindEvents();
this.render();
}

bindEvents() {
// Event delegation: 1 event listener instead of hundreds
this.table.addEventListener('change', (e) => {
if (e.target.matches('.row-checkbox')) {
this.toggleRow(e.target.dataset.id, e.target.checked);
}
if (e.target.matches('#select-all')) {
this.toggleAll(e.target.checked);
}
});

this.deleteBtn?.addEventListener('click', () => this.handleDelete());
}

toggleRow(id, isChecked) {
isChecked ? this.selectedIds.add(id) : this.selectedIds.delete(id);
this.render();
}

toggleAll(isChecked) {
const boxes = this.table.querySelectorAll('.row-checkbox:not([disabled])');
boxes.forEach(box => {
box.checked = isChecked;
this.toggleRow(box.dataset.id, isChecked);
});
}

render() {
const count = this.selectedIds.size;
this.countEl.textContent = count;
this.deleteBtn.disabled = count === 0;

// Update 'select-all' checkbox indeterminate state
const allBoxes = this.table.querySelectorAll('.row-checkbox:not([disabled])');
const selectAll = this.table.querySelector('#select-all');
if (selectAll) {
selectAll.checked = count > 0 && count === allBoxes.length;
selectAll.indeterminate = count > 0 && count < allBoxes.length;
}
}

async handleDelete() {
const ids = [...this.selectedIds].map(Number);
if (!ids.length) return;

const confirmed = confirm(`Delete ${ids.length} items? This action cannot be undone.`);
if (!confirmed) return;

this.deleteBtn.disabled = true;
this.deleteBtn.textContent = 'Deleting...';

try {
const res = await fetch('/api/items', {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ ids })
});

if (!res.ok) throw new Error('Delete operation failed');

// FDD Requirement: Show toast on success
this.showToast(`Successfully deleted ${ids.length} items`);

// FDD Requirement: Cleanly remove rows from the DOM
ids.forEach(id => {
this.table.querySelector(`tr[data-id="${id}"]`)?.remove();
});

// FDD Requirement: Trigger analytics
window.analytics?.track('bulk_delete_count', { count: ids.length });

this.selectedIds.clear();
} catch (err) {
this.showToast('Failed to delete items. Please try again.', 'error');
} finally {
this.render();
this.deleteBtn.textContent = 'Delete Selected';
}
}

showToast(msg, type = 'success') {
// Standardized toast implementation defined in our system architecture
console.log(`[${type.toUpperCase()}] ${msg}`);
}
}

// Initialize when the DOM is fully loaded
document.addEventListener('DOMContentLoaded', () => {
new BulkDeleteController('#admin-table');
});









The HTML Structure



This markup matches the exact interface promised by our FDD:




CODE
<table id="admin-table">
<thead>
<tr>
<th><input type="checkbox" id="select-all"></th>
<th>Name</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr data-id="1">
<td><input type="checkbox" class="row-checkbox" data-id="1"></td>
<td>Item 1</td>
<td>active</td>
</tr>
<tr data-id="2" data-status="locked">
<td><input type="checkbox" class="row-checkbox" data-id="2" disabled></td>
<td>Item 2</td>
<td>locked</td>
</tr>
</tbody>
</table>

<div class="bulk-actions">
<span><span id="selected-count">0</span> selected</span>
<button id="bulk-delete-btn" disabled>Delete Selected</button>
</div>












5. Validation Checks as Code



An FDD ensures that code remains testable and predictable. The functional requirements map directly to our code logic:






































Check User Action Expected Behavior Code Proof
Multi-Select Flow Check 3 boxes, click Delete Confirm modal shows accurate count.
confirm(\Delete ${ids.length} items?)
Select-All Logic Click header checkbox All un-locked rows get checked. querySelectorAll('.row-checkbox:not([disabled])')
Role Guard Load page as a 'viewer' role No select elements render. if (!canBulkDelete) return;
Empty State Deselect all active items Delete button returns to disabled state. this.deleteBtn.disabled = count === 0;



Rule of Thumb: If your functional design cannot be directly mapped to a validation check in code like the table above, the design is incomplete.










6. Business Benefits = Engineering Benefits





  1. Accurate Development: The written code does precisely what the FDD laid out. No guesswork required.


  2. Faster Delivery Times: You don't have to pause development mid-sprint to debate browser confirm() dialogue versus building a custom modal component. It was decided and documented beforehand.


  3. Streamlined Onboarding: A new engineer can read the FDD, inspect the Vanilla JS class, and immediately understand the relationship between feature expectations and technical implementation.


  4. Minimal Scope Creep: Hard edge cases like "what happens to locked items?" are addressed and validated before staging a single commit.









Conclusion



Code is simply our agreed-upon process, automated.



Writing Vanilla JS doesn't mean skipping best practices. It means choosing lightweight processes that keep you moving. 60 lines of vanilla JS backed by a 1-page FDD is faster, more performant, and more stable than 600 lines of framework boilerplate built without a plan.






Quick FDD Template



Copy and drop this outline into /docs/fdd/ on your next project:




CODE
# FDD: [Feature Name]

## 1. GAP Analysis
* What is missing or broken in the current UI/UX?

## 2. Solution Overview
* High-level summary of what we are building.

## 3. UI/UX Changes
* DOM modifications, states (empty, loading, disabled), and user pathways.

## 4. Business Logic & Edge Cases
* Roles/permissions, constraints, and conditional behavior.

## 5. Data & API Contract
* Payload requirements and endpoint changes.

## 6. Validation Checks
* How we prove the feature works as intended.

## 7. Impact Analysis
* What existing features could this change touch or break?






Make this simple documentation change, and your next pull request will focus on code quality, not architectural debate.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
7 Quellen
CVE-2024-44946 | Linux Kernel up to 6.1.106/6.6.47/6.10.6 include/linux/skbuff.h kcm_release use after free (Nessus ID 208099 / WID-SEC-2024-2057)
6 Quellen
CVE-2026-87591 | Google Chrome up to 152.0.7977.82 Extensions improper authorization
1 Quelle
CVE-2026-90843 | SabyasachiRana WebMap up to 8b95fe4dc301a3c09ddf145b895de0bf9f8d2a25 New Nmap Scan functions_nmap.py nmap_newscan target/params os command injection
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten The FDD for Vanilla JS: The 20-Min Doc That Saves 2 Days of Rework

Thematisch verwandte Begriffe: Vanilla, 20Min, That, Saves · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...