Fix Job Posting Generator template implementation issues

- Fix CSS variable inconsistencies in form validation (use --success, --error, --primary)
- Implement missing security with safeSetHTML in displayResults function
- Complete debouncing implementation for form interactions and textarea auto-resize
- Clean up duplicate event listeners and consolidate initialization
- Ensure all form validation uses proper CSS variables
- Add proper debounced validation for real-time form feedback
- Remove duplicate DOMContentLoaded event listener

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Claude 2025-07-18 19:52:12 +05:30
parent c0d071408d
commit 6bb07d16ae

View File

@ -1285,51 +1285,65 @@ document.addEventListener('keydown', function(e) {
} }
// Enhanced form validation with visual feedback // Enhanced form validation with visual feedback and debouncing
function validateField(field) { const debouncedValidateField = createDebouncer(function(field) {
const isValid = field.value.trim() !== ''; const isValid = field.value.trim() !== '';
const container = field.closest('.form-group') || field.parentElement; const container = field.closest('.form-group') || field.parentElement;
if (isValid) { if (isValid) {
field.style.borderColor = 'var(--success-color)'; field.style.borderColor = 'var(--success)';
field.style.boxShadow = '0 0 0 2px rgba(16, 185, 129, 0.1)'; field.style.boxShadow = '0 0 0 2px rgba(16, 185, 129, 0.1)';
container.classList.remove('error'); container.classList.remove('error');
} else { } else {
field.style.borderColor = 'var(--error-color)'; field.style.borderColor = 'var(--error)';
field.style.boxShadow = '0 0 0 2px rgba(239, 68, 68, 0.1)'; field.style.boxShadow = '0 0 0 2px rgba(239, 68, 68, 0.1)';
container.classList.add('error'); container.classList.add('error');
} }
return isValid; return isValid;
}, 300);
function validateField(field) {
return debouncedValidateField(field);
} }
// Progressive form enhancement // Progressive form enhancement with debouncing
function initializeFormEnhancements() { function initializeFormEnhancements() {
const requiredFields = document.querySelectorAll('[required]'); const requiredFields = document.querySelectorAll('[required]');
// Debounced textarea auto-resize
const debouncedResize = createDebouncer(function(textarea) {
textarea.style.height = 'auto';
textarea.style.height = Math.max(120, textarea.scrollHeight) + 'px';
}, 100);
requiredFields.forEach(field => { requiredFields.forEach(field => {
// Real-time validation // Real-time validation with debouncing
field.addEventListener('input', () => {
if (field.value.trim()) {
debouncedValidateField(field);
}
});
field.addEventListener('blur', () => validateField(field)); field.addEventListener('blur', () => validateField(field));
// Reset validation on focus // Reset validation on focus
field.addEventListener('focus', () => { field.addEventListener('focus', () => {
field.style.borderColor = 'var(--primary-color)'; field.style.borderColor = 'var(--primary)';
field.style.boxShadow = '0 0 0 2px rgba(0, 0, 0, 0.1)'; field.style.boxShadow = '0 0 0 2px rgba(0, 0, 0, 0.1)';
field.closest('.form-group')?.classList.remove('error'); field.closest('.form-group')?.classList.remove('error');
}); });
// Auto-resize textareas // Auto-resize textareas with debouncing
if (field.tagName === 'TEXTAREA') { if (field.tagName === 'TEXTAREA') {
field.addEventListener('input', function() { field.addEventListener('input', function() {
this.style.height = 'auto'; debouncedResize(this);
this.style.height = Math.max(120, this.scrollHeight) + 'px';
}); });
} }
}); });
} }
// Initialize on page load // Form enhancements are initialized in the main DOMContentLoaded listener above
document.addEventListener('DOMContentLoaded', initializeFormEnhancements);
@ -1378,8 +1392,8 @@ document.addEventListener('keydown', function(e) {
// Format job posting content with professional styling // Format job posting content with professional styling
const formattedContent = formatJobPostingContent(content); const formattedContent = formatJobPostingContent(content);
// Update content // Update content with safe HTML
contentElement.innerHTML = formattedContent; safeSetHTML(contentElement, formattedContent);
// Show results // Show results
resultsContainer.style.display = 'block'; resultsContainer.style.display = 'block';