
Service Request
Auto • Diesel • Trailer Repair • 24/7 Roadside Service
HSCO Service Request Form
Progress
0% Complete
✓ Form automatically saved
${(file.size / 1024 / 1024).toFixed(2)} MB
`;
fileInfo.appendChild(thumbnail);
fileInfo.appendChild(fileDetails);
// Delete button
const deleteBtn = document.createElement('button');
deleteBtn.type = 'button';
deleteBtn.className = 'text-red-600 hover:text-red-800 font-medium px-3 py-1 rounded border border-red-300 hover:border-red-500 focus:outline-none focus:ring-2 focus:ring-red-500';
deleteBtn.textContent = 'Remove';
deleteBtn.setAttribute('aria-label', `Remove ${file.name}`);
deleteBtn.addEventListener('click', function() {
removeFile(file.id);
});
photoItem.appendChild(fileInfo);
photoItem.appendChild(deleteBtn);
photoList.appendChild(photoItem);
});
}
function removeFile(fileId) {
selectedFiles = selectedFiles.filter(file => file.id !== fileId);
displayPhotoPreview();
updateFileInput();
updateProgress();
triggerAutoSave();
}
function updateFileInput() {
// Create new FileList from selectedFiles
const dt = new DataTransfer();
selectedFiles.forEach(file => {
dt.items.add(file);
});
photoInput.files = dt.files;
}
// Real-time validation for all inputs
const inputs = form.querySelectorAll('input, select, textarea');
inputs.forEach(input => {
input.addEventListener('input', function() {
validateField(this);
updateProgress();
triggerAutoSave();
});
input.addEventListener('blur', function() {
validateField(this);
});
});
function validateField(field) {
const errorDiv = document.getElementById(`${field.id}-error`);
if (!errorDiv) return;
let errorMessage = '';
if (field.validity.valueMissing) {
errorMessage = 'This field is required.';
} else if (field.validity.typeMismatch) {
if (field.type === 'email') {
errorMessage = 'Please enter a valid email address.';
} else if (field.type === 'tel') {
errorMessage = 'Please enter a valid phone number.';
}
} else if (field.validity.patternMismatch) {
if (field.id === 'vinNumber') {
errorMessage = 'VIN must be exactly 17 characters (no I, O, or Q).';
} else if (field.type === 'tel') {
errorMessage = 'Please use format: 123-456-7890';
}
} else if (field.validity.rangeUnderflow || field.validity.rangeOverflow) {
if (field.type === 'number') {
errorMessage = `Please enter a year between ${field.min} and ${field.max}.`;
}
}
if (errorMessage) {
errorDiv.textContent = errorMessage;
errorDiv.classList.remove('hidden');
field.setAttribute('aria-invalid', 'true');
} else {
errorDiv.classList.add('hidden');
field.setAttribute('aria-invalid', 'false');
}
}
// Form submission with loading state
form.addEventListener('submit', function(e) {
e.preventDefault();
// Final validation
let isValid = true;
inputs.forEach(input => {
validateField(input);
if (!input.checkValidity()) {
isValid = false;
}
});
// Check service type checkboxes
const serviceTypeChecked = Array.from(checkboxes).some(cb => cb.checked);
const serviceTypeError = document.getElementById('serviceType-error');
if (!serviceTypeChecked) {
serviceTypeError.textContent = 'Please select at least one service type.';
serviceTypeError.classList.remove('hidden');
isValid = false;
}
if (!isValid) {
// Scroll to first error
const firstError = form.querySelector('.error-message:not(.hidden)');
if (firstError) {
firstError.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
return;
}
// Show loading state
submitBtn.disabled = true;
submitText.classList.add('hidden');
loadingText.classList.remove('hidden');
// Submit form (remove preventDefault in real implementation)
// Simulate submission delay for demo
setTimeout(() => {
// In real implementation, remove this setTimeout and the preventDefault above
alert('Form submitte