javascript
examples
examples.js⚡javascript
/**
* ========================================
* 10.5 Forms and User Input - Examples
* ========================================
*
* Run these examples in a browser console with appropriate HTML forms
* or create the forms dynamically as shown.
*/
/**
* ========================================
* EXAMPLE 1: Creating a Form Dynamically
* ========================================
*/
console.log('--- Example 1: Creating a Form Dynamically ---');
// Create a complete form structure
function createContactForm() {
const form = document.createElement('form');
form.id = 'contactForm';
form.innerHTML = `
<div class="form-group">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required minlength="2">
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="subject">Subject:</label>
<select id="subject" name="subject">
<option value="">Select a subject</option>
<option value="general">General Inquiry</option>
<option value="support">Support</option>
<option value="feedback">Feedback</option>
</select>
</div>
<div class="form-group">
<label for="message">Message:</label>
<textarea id="message" name="message" rows="4" required></textarea>
</div>
<div class="form-group">
<label>
<input type="checkbox" name="newsletter" value="yes">
Subscribe to newsletter
</label>
</div>
<button type="submit">Send Message</button>
<button type="reset">Clear Form</button>
`;
return form;
}
// Usage (uncomment to test in browser):
// document.body.appendChild(createContactForm());
/**
* ========================================
* EXAMPLE 2: Accessing Form Elements
* ========================================
*/
console.log('\n--- Example 2: Accessing Form Elements ---');
function demonstrateFormAccess() {
// Assuming form exists in DOM
const form = document.getElementById('contactForm');
if (!form) {
console.log('Create a form first');
return;
}
// Access via elements collection
console.log('Form elements count:', form.elements.length);
console.log('Name field:', form.elements['name']);
console.log('Email field:', form.elements['email']);
console.log('First element:', form.elements[0]);
// Iterate all form elements
console.log('\nAll form elements:');
for (let i = 0; i < form.elements.length; i++) {
const element = form.elements[i];
console.log(
`${i}: ${element.tagName} - name="${element.name}" type="${element.type}"`
);
}
// Access all forms in document
console.log('\nAll forms in document:', document.forms.length);
}
// demonstrateFormAccess();
/**
* ========================================
* EXAMPLE 3: Reading Different Input Types
* ========================================
*/
console.log('\n--- Example 3: Reading Different Input Types ---');
function createInputTypesDemo() {
const form = document.createElement('form');
form.id = 'inputTypesForm';
form.innerHTML = `
<h3>Input Types Demo</h3>
<!-- Text input -->
<input type="text" name="textInput" value="Hello World">
<!-- Number input -->
<input type="number" name="numberInput" value="42">
<!-- Checkbox -->
<input type="checkbox" name="checkboxInput" checked>
<!-- Radio buttons -->
<input type="radio" name="radioInput" value="option1" checked> Option 1
<input type="radio" name="radioInput" value="option2"> Option 2
<!-- Select -->
<select name="selectInput">
<option value="a">Option A</option>
<option value="b" selected>Option B</option>
<option value="c">Option C</option>
</select>
<!-- Multi-select -->
<select name="multiSelect" multiple>
<option value="1" selected>One</option>
<option value="2" selected>Two</option>
<option value="3">Three</option>
</select>
<!-- Range -->
<input type="range" name="rangeInput" min="0" max="100" value="50">
<!-- Color -->
<input type="color" name="colorInput" value="#3498db">
<!-- Date -->
<input type="date" name="dateInput" value="2024-01-15">
<button type="button" onclick="readAllInputs()">Read All Values</button>
`;
return form;
}
function readAllInputs() {
const form = document.getElementById('inputTypesForm');
if (!form) return;
// Text input
const textValue = form.elements['textInput'].value;
console.log('Text:', textValue);
// Number input (still returns string, need to convert)
const numberValue = Number(form.elements['numberInput'].value);
console.log('Number:', numberValue, typeof numberValue);
// Checkbox
const checkboxValue = form.elements['checkboxInput'].checked;
console.log('Checkbox:', checkboxValue);
// Radio buttons (find the checked one)
const radioValue = form.querySelector(
'input[name="radioInput"]:checked'
).value;
console.log('Radio:', radioValue);
// Select
const selectValue = form.elements['selectInput'].value;
console.log('Select:', selectValue);
// Multi-select (get all selected)
const multiSelect = form.elements['multiSelect'];
const multiValues = [...multiSelect.selectedOptions].map((opt) => opt.value);
console.log('Multi-select:', multiValues);
// Range
const rangeValue = Number(form.elements['rangeInput'].value);
console.log('Range:', rangeValue);
// Color
const colorValue = form.elements['colorInput'].value;
console.log('Color:', colorValue);
// Date
const dateValue = form.elements['dateInput'].value;
console.log('Date:', dateValue);
}
/**
* ========================================
* EXAMPLE 4: HTML5 Form Validation
* ========================================
*/
console.log('\n--- Example 4: HTML5 Form Validation ---');
function createValidationForm() {
const form = document.createElement('form');
form.id = 'validationForm';
form.innerHTML = `
<div>
<label>Username (3-15 chars, letters only):</label>
<input type="text" name="username"
required
minlength="3"
maxlength="15"
pattern="[A-Za-z]+"
title="Only letters allowed">
<span class="error"></span>
</div>
<div>
<label>Email:</label>
<input type="email" name="email" required>
<span class="error"></span>
</div>
<div>
<label>Age (18-99):</label>
<input type="number" name="age"
required
min="18"
max="99">
<span class="error"></span>
</div>
<div>
<label>Website:</label>
<input type="url" name="website">
<span class="error"></span>
</div>
<button type="submit">Validate & Submit</button>
`;
// Add validation handler
form.addEventListener('submit', function (e) {
e.preventDefault();
if (form.checkValidity()) {
console.log('Form is valid! Submitting...');
// Process form
} else {
console.log('Form has validation errors');
form.reportValidity();
}
});
return form;
}
/**
* ========================================
* EXAMPLE 5: Constraint Validation API
* ========================================
*/
console.log('\n--- Example 5: Constraint Validation API ---');
function demonstrateValidityAPI() {
const input = document.createElement('input');
input.type = 'email';
input.required = true;
input.value = '';
console.log('Empty required email field validity:');
console.log('- valid:', input.validity.valid);
console.log('- valueMissing:', input.validity.valueMissing);
input.value = 'not-an-email';
console.log('\nInvalid email format:');
console.log('- valid:', input.validity.valid);
console.log('- typeMismatch:', input.validity.typeMismatch);
input.value = 'valid@email.com';
console.log('\nValid email:');
console.log('- valid:', input.validity.valid);
// Number validation
const numberInput = document.createElement('input');
numberInput.type = 'number';
numberInput.min = '10';
numberInput.max = '20';
numberInput.value = '5';
console.log('\nNumber below minimum (5 with min=10):');
console.log('- rangeUnderflow:', numberInput.validity.rangeUnderflow);
numberInput.value = '25';
console.log('\nNumber above maximum (25 with max=20):');
console.log('- rangeOverflow:', numberInput.validity.rangeOverflow);
}
demonstrateValidityAPI();
/**
* ========================================
* EXAMPLE 6: Custom Validation
* ========================================
*/
console.log('\n--- Example 6: Custom Validation ---');
function createPasswordForm() {
const form = document.createElement('form');
form.id = 'passwordForm';
form.innerHTML = `
<div>
<label>Password:</label>
<input type="password" id="password" name="password" required minlength="8">
<small>At least 8 characters, one uppercase, one number</small>
</div>
<div>
<label>Confirm Password:</label>
<input type="password" id="confirmPassword" name="confirmPassword" required>
</div>
<button type="submit">Create Account</button>
`;
const password = form.querySelector('#password');
const confirmPassword = form.querySelector('#confirmPassword');
// Custom password strength validation
function validatePasswordStrength() {
const value = password.value;
if (!/[A-Z]/.test(value)) {
password.setCustomValidity('Password must contain an uppercase letter');
} else if (!/[0-9]/.test(value)) {
password.setCustomValidity('Password must contain a number');
} else {
password.setCustomValidity('');
}
}
// Password match validation
function validatePasswordMatch() {
if (password.value !== confirmPassword.value) {
confirmPassword.setCustomValidity("Passwords don't match");
} else {
confirmPassword.setCustomValidity('');
}
}
password.addEventListener('input', () => {
validatePasswordStrength();
validatePasswordMatch();
});
confirmPassword.addEventListener('input', validatePasswordMatch);
form.addEventListener('submit', function (e) {
e.preventDefault();
if (form.checkValidity()) {
console.log('Passwords valid and matching!');
} else {
form.reportValidity();
}
});
return form;
}
/**
* ========================================
* EXAMPLE 7: Real-time Validation Feedback
* ========================================
*/
console.log('\n--- Example 7: Real-time Validation Feedback ---');
function createRealtimeValidationForm() {
const form = document.createElement('form');
form.id = 'realtimeForm';
form.innerHTML = `
<style>
.valid { border-color: green; }
.invalid { border-color: red; }
.feedback { font-size: 12px; margin-top: 4px; }
.feedback.success { color: green; }
.feedback.error { color: red; }
</style>
<div>
<label>Username:</label>
<input type="text" id="rtUsername" required minlength="3" maxlength="20">
<div id="usernameFeedback" class="feedback"></div>
</div>
<div>
<label>Email:</label>
<input type="email" id="rtEmail" required>
<div id="emailFeedback" class="feedback"></div>
</div>
`;
const username = form.querySelector('#rtUsername');
const usernameFeedback = form.querySelector('#usernameFeedback');
const email = form.querySelector('#rtEmail');
const emailFeedback = form.querySelector('#emailFeedback');
username.addEventListener('input', function () {
const validity = this.validity;
if (validity.valid) {
this.classList.remove('invalid');
this.classList.add('valid');
usernameFeedback.textContent = '✓ Username looks good!';
usernameFeedback.className = 'feedback success';
} else if (validity.valueMissing) {
this.classList.remove('valid');
this.classList.add('invalid');
usernameFeedback.textContent = '✗ Username is required';
usernameFeedback.className = 'feedback error';
} else if (validity.tooShort) {
this.classList.remove('valid');
this.classList.add('invalid');
usernameFeedback.textContent = `✗ At least ${this.minLength} characters (${this.value.length}/${this.minLength})`;
usernameFeedback.className = 'feedback error';
}
});
email.addEventListener('input', function () {
if (this.validity.valid) {
this.classList.remove('invalid');
this.classList.add('valid');
emailFeedback.textContent = '✓ Valid email';
emailFeedback.className = 'feedback success';
} else if (this.validity.typeMismatch) {
this.classList.remove('valid');
this.classList.add('invalid');
emailFeedback.textContent = '✗ Please enter a valid email';
emailFeedback.className = 'feedback error';
} else if (this.validity.valueMissing) {
this.classList.remove('valid');
this.classList.add('invalid');
emailFeedback.textContent = '✗ Email is required';
emailFeedback.className = 'feedback error';
}
});
return form;
}
/**
* ========================================
* EXAMPLE 8: FormData API
* ========================================
*/
console.log('\n--- Example 8: FormData API ---');
function demonstrateFormData() {
// Create a form programmatically
const form = document.createElement('form');
form.innerHTML = `
<input type="text" name="firstName" value="John">
<input type="text" name="lastName" value="Doe">
<input type="email" name="email" value="john@example.com">
<input type="checkbox" name="interests" value="javascript" checked>
<input type="checkbox" name="interests" value="python" checked>
<input type="checkbox" name="interests" value="rust">
`;
const formData = new FormData(form);
console.log('FormData operations:');
// Get single value
console.log('firstName:', formData.get('firstName'));
// Get all values for a key (checkboxes)
console.log('interests:', formData.getAll('interests'));
// Check if key exists
console.log('has email:', formData.has('email'));
console.log('has phone:', formData.has('phone'));
// Add new value
formData.append('timestamp', Date.now().toString());
console.log('timestamp:', formData.get('timestamp'));
// Iterate entries
console.log('\nAll entries:');
for (const [key, value] of formData.entries()) {
console.log(` ${key}: ${value}`);
}
// Convert to object
const dataObject = Object.fromEntries(formData);
console.log('\nAs object:', dataObject);
// Note: Object.fromEntries only gets LAST value for duplicate keys
// Better conversion for multiple values
const fullData = {};
for (const [key, value] of formData.entries()) {
if (fullData[key]) {
if (Array.isArray(fullData[key])) {
fullData[key].push(value);
} else {
fullData[key] = [fullData[key], value];
}
} else {
fullData[key] = value;
}
}
console.log('Full data with arrays:', fullData);
}
demonstrateFormData();
/**
* ========================================
* EXAMPLE 9: Form Submission with Fetch
* ========================================
*/
console.log('\n--- Example 9: Form Submission with Fetch ---');
function createAjaxForm() {
const form = document.createElement('form');
form.id = 'ajaxForm';
form.innerHTML = `
<input type="text" name="title" placeholder="Title" required>
<textarea name="content" placeholder="Content" required></textarea>
<button type="submit">Submit</button>
<div id="status"></div>
`;
const statusDiv = form.querySelector('#status');
form.addEventListener('submit', async function (e) {
e.preventDefault();
const formData = new FormData(form);
const data = Object.fromEntries(formData);
statusDiv.textContent = 'Submitting...';
try {
// Simulated API call
const response = await fetch(
'https://jsonplaceholder.typicode.com/posts',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
}
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
console.log('Server response:', result);
statusDiv.textContent = `Success! Created post with ID: ${result.id}`;
form.reset();
} catch (error) {
console.error('Submission error:', error);
statusDiv.textContent = `Error: ${error.message}`;
}
});
return form;
}
/**
* ========================================
* EXAMPLE 10: Input Events
* ========================================
*/
console.log('\n--- Example 10: Input Events ---');
function createInputEventsDemo() {
const container = document.createElement('div');
container.innerHTML = `
<h3>Input Events Demo</h3>
<input type="text" id="eventInput" placeholder="Type something...">
<div id="eventLog" style="height: 200px; overflow-y: auto; border: 1px solid #ccc; padding: 10px;"></div>
`;
const input = container.querySelector('#eventInput');
const log = container.querySelector('#eventLog');
function logEvent(eventName, details = '') {
const entry = document.createElement('div');
const time = new Date().toLocaleTimeString();
entry.textContent = `[${time}] ${eventName} ${details}`;
log.appendChild(entry);
log.scrollTop = log.scrollHeight;
}
// Input event - fires on every change
input.addEventListener('input', function (e) {
logEvent('input', `value="${this.value}"`);
});
// Change event - fires on blur when value changed
input.addEventListener('change', function (e) {
logEvent('change', `value="${this.value}"`);
});
// Focus events
input.addEventListener('focus', function () {
logEvent('focus');
});
input.addEventListener('blur', function () {
logEvent('blur');
});
// Keyboard events
input.addEventListener('keydown', function (e) {
logEvent('keydown', `key="${e.key}"`);
});
input.addEventListener('keyup', function (e) {
logEvent('keyup', `key="${e.key}"`);
});
return container;
}
/**
* ========================================
* EXAMPLE 11: Debounced Search Input
* ========================================
*/
console.log('\n--- Example 11: Debounced Search Input ---');
function debounce(func, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
function createSearchInput() {
const container = document.createElement('div');
container.innerHTML = `
<label>Search:</label>
<input type="text" id="searchInput" placeholder="Type to search...">
<div id="searchResults"></div>
`;
const input = container.querySelector('#searchInput');
const results = container.querySelector('#searchResults');
// Simulated search function
function performSearch(query) {
console.log(`Searching for: "${query}"`);
results.textContent = `Searching for: "${query}"...`;
// Simulate API delay
setTimeout(() => {
results.textContent = `Found 5 results for "${query}"`;
}, 500);
}
// Debounced search - only fires 300ms after user stops typing
const debouncedSearch = debounce(function (e) {
const query = e.target.value.trim();
if (query.length >= 2) {
performSearch(query);
} else {
results.textContent = 'Type at least 2 characters';
}
}, 300);
input.addEventListener('input', debouncedSearch);
return container;
}
/**
* ========================================
* EXAMPLE 12: File Input Handling
* ========================================
*/
console.log('\n--- Example 12: File Input Handling ---');
function createFileUploadForm() {
const form = document.createElement('form');
form.innerHTML = `
<div>
<label>Select files:</label>
<input type="file" id="fileInput" multiple accept="image/*,.pdf">
</div>
<div id="fileList"></div>
<div id="preview"></div>
`;
const fileInput = form.querySelector('#fileInput');
const fileList = form.querySelector('#fileList');
const preview = form.querySelector('#preview');
fileInput.addEventListener('change', function () {
const files = this.files;
if (files.length === 0) {
fileList.textContent = 'No files selected';
return;
}
// Display file information
let html = '<h4>Selected Files:</h4><ul>';
for (const file of files) {
const size = (file.size / 1024).toFixed(2);
html += `<li>
${file.name}
(${file.type || 'unknown type'}, ${size} KB)
</li>`;
}
html += '</ul>';
fileList.innerHTML = html;
// Preview images
preview.innerHTML = '';
for (const file of files) {
if (file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = function (e) {
const img = document.createElement('img');
img.src = e.target.result;
img.style.maxWidth = '200px';
img.style.margin = '10px';
preview.appendChild(img);
};
reader.readAsDataURL(file);
}
}
});
return form;
}
/**
* ========================================
* EXAMPLE 13: Form with All Input Types
* ========================================
*/
console.log('\n--- Example 13: Complete Form Example ---');
function createCompleteForm() {
const form = document.createElement('form');
form.id = 'completeForm';
form.innerHTML = `
<style>
.form-group { margin-bottom: 15px; }
.form-group label { display: block; margin-bottom: 5px; font-weight: bold; }
.form-group input, .form-group select, .form-group textarea {
width: 100%; padding: 8px; box-sizing: border-box;
}
.form-group.inline label { display: inline; font-weight: normal; }
.error-message { color: red; font-size: 12px; }
button { padding: 10px 20px; margin-right: 10px; cursor: pointer; }
</style>
<h2>User Registration</h2>
<div class="form-group">
<label for="username">Username *</label>
<input type="text" id="username" name="username" required minlength="3" maxlength="20">
</div>
<div class="form-group">
<label for="email">Email *</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-group">
<label for="password">Password *</label>
<input type="password" id="password" name="password" required minlength="8">
</div>
<div class="form-group">
<label for="birthdate">Birth Date</label>
<input type="date" id="birthdate" name="birthdate">
</div>
<div class="form-group">
<label for="country">Country</label>
<select id="country" name="country">
<option value="">Select country</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
<option value="ca">Canada</option>
<option value="au">Australia</option>
</select>
</div>
<div class="form-group">
<label>Gender</label>
<label class="inline">
<input type="radio" name="gender" value="male"> Male
</label>
<label class="inline">
<input type="radio" name="gender" value="female"> Female
</label>
<label class="inline">
<input type="radio" name="gender" value="other"> Other
</label>
</div>
<div class="form-group">
<label>Interests</label>
<label class="inline">
<input type="checkbox" name="interests" value="tech"> Technology
</label>
<label class="inline">
<input type="checkbox" name="interests" value="sports"> Sports
</label>
<label class="inline">
<input type="checkbox" name="interests" value="music"> Music
</label>
</div>
<div class="form-group">
<label for="bio">Bio</label>
<textarea id="bio" name="bio" rows="4" placeholder="Tell us about yourself..."></textarea>
</div>
<div class="form-group">
<label for="avatar">Profile Picture</label>
<input type="file" id="avatar" name="avatar" accept="image/*">
</div>
<div class="form-group">
<label class="inline">
<input type="checkbox" name="terms" required>
I agree to the Terms and Conditions *
</label>
</div>
<button type="submit">Register</button>
<button type="reset">Clear</button>
<div id="formOutput"></div>
`;
form.addEventListener('submit', function (e) {
e.preventDefault();
const formData = new FormData(form);
const output = form.querySelector('#formOutput');
// Build output
let html = '<h3>Form Data:</h3><pre>';
// Regular fields
for (const [key, value] of formData.entries()) {
if (value instanceof File) {
html += `${key}: [File] ${value.name} (${value.size} bytes)\n`;
} else {
html += `${key}: ${value}\n`;
}
}
html += '</pre>';
output.innerHTML = html;
console.log('Form submitted:', Object.fromEntries(formData));
});
form.addEventListener('reset', function () {
form.querySelector('#formOutput').innerHTML = '';
});
return form;
}
/**
* ========================================
* EXAMPLE 14: Preventing Double Submission
* ========================================
*/
console.log('\n--- Example 14: Preventing Double Submission ---');
function createSubmitOnceForm() {
const form = document.createElement('form');
form.innerHTML = `
<input type="text" name="data" required placeholder="Enter data">
<button type="submit" id="submitBtn">Submit</button>
<span id="submitStatus"></span>
`;
const submitBtn = form.querySelector('#submitBtn');
const status = form.querySelector('#submitStatus');
form.addEventListener('submit', async function (e) {
e.preventDefault();
// Disable button immediately
submitBtn.disabled = true;
const originalText = submitBtn.textContent;
submitBtn.textContent = 'Submitting...';
status.textContent = '';
try {
// Simulate slow API call
await new Promise((resolve) => setTimeout(resolve, 2000));
// Simulate random success/failure
if (Math.random() > 0.3) {
status.textContent = '✓ Success!';
status.style.color = 'green';
form.reset();
} else {
throw new Error('Random server error');
}
} catch (error) {
status.textContent = `✗ Error: ${error.message}`;
status.style.color = 'red';
} finally {
// Re-enable button
submitBtn.disabled = false;
submitBtn.textContent = originalText;
}
});
return form;
}
/**
* ========================================
* EXAMPLE 15: Dynamic Form Fields
* ========================================
*/
console.log('\n--- Example 15: Dynamic Form Fields ---');
function createDynamicForm() {
const form = document.createElement('form');
form.innerHTML = `
<div id="fieldsContainer">
<div class="field-row">
<input type="text" name="items[]" placeholder="Item 1" required>
<button type="button" class="remove-btn">Remove</button>
</div>
</div>
<button type="button" id="addField">+ Add Item</button>
<button type="submit">Submit</button>
`;
const container = form.querySelector('#fieldsContainer');
const addBtn = form.querySelector('#addField');
let itemCount = 1;
addBtn.addEventListener('click', function () {
itemCount++;
const newRow = document.createElement('div');
newRow.className = 'field-row';
newRow.innerHTML = `
<input type="text" name="items[]" placeholder="Item ${itemCount}" required>
<button type="button" class="remove-btn">Remove</button>
`;
container.appendChild(newRow);
});
// Event delegation for remove buttons
container.addEventListener('click', function (e) {
if (e.target.classList.contains('remove-btn')) {
const rows = container.querySelectorAll('.field-row');
if (rows.length > 1) {
e.target.closest('.field-row').remove();
} else {
alert('Must have at least one item');
}
}
});
form.addEventListener('submit', function (e) {
e.preventDefault();
const formData = new FormData(form);
const items = formData.getAll('items[]');
console.log('Items:', items);
});
return form;
}
/**
* ========================================
* Running Examples
* ========================================
*/
console.log('\n========================================');
console.log('Forms and User Input Examples');
console.log('========================================');
console.log('To run examples in browser, use these functions:');
console.log('- document.body.appendChild(createContactForm())');
console.log('- document.body.appendChild(createInputTypesDemo())');
console.log('- document.body.appendChild(createValidationForm())');
console.log('- document.body.appendChild(createPasswordForm())');
console.log('- document.body.appendChild(createRealtimeValidationForm())');
console.log('- document.body.appendChild(createAjaxForm())');
console.log('- document.body.appendChild(createInputEventsDemo())');
console.log('- document.body.appendChild(createSearchInput())');
console.log('- document.body.appendChild(createFileUploadForm())');
console.log('- document.body.appendChild(createCompleteForm())');
console.log('- document.body.appendChild(createSubmitOnceForm())');
console.log('- document.body.appendChild(createDynamicForm())');