I can help you resolve this - I’ve implemented robust form validation in the partner portal for multiple zs-2021 deployments. Your issue spans all three critical areas: form event binding, validation logic execution, and user feedback on errors.
Form Event Binding:
The primary issue is that the partner portal in zs-2021 uses a custom form submission handler that bypasses standard submit events. You need to bind to the portal’s specific validation hook:
window.addEventListener('DOMContentLoaded', function() {
const form = document.querySelector('#partner-form');
if (form) {
form.addEventListener('submit', validateForm, true);
}
});
The third parameter true enables event capturing, which ensures your handler runs before Zendesk’s internal handlers. Additionally, the partner portal dynamically loads forms, so wrapping in DOMContentLoaded ensures the form exists when you try to bind.
However, the real solution requires intercepting the portal’s AJAX submission:
const originalSubmit = HTMLFormElement.prototype.submit;
HTMLFormElement.prototype.submit = function() {
if (this.id === 'partner-form' && !validateForm(this)) {
return false;
}
originalSubmit.call(this);
};
Validation Logic Execution:
Your current validation only checks email and doesn’t prevent submission properly. Here’s a comprehensive validation implementation:
function validateForm(e) {
const form = e.target || e;
let isValid = true;
const errors = [];
// Email validation
const emailField = form.querySelector('[name="email"]');
if (!validateEmail(emailField.value)) {
errors.push({field: emailField, message: 'Invalid email format'});
isValid = false;
}
// Required fields validation
const requiredFields = form.querySelectorAll('[required]');
requiredFields.forEach(field => {
if (!field.value.trim()) {
errors.push({field: field, message: 'This field is required'});
isValid = false;
}
});
if (!isValid) {
e.preventDefault();
e.stopPropagation();
displayErrors(errors);
return false;
}
return true;
}
The key is using both preventDefault() and stopPropagation() to completely halt the submission process, plus returning false.
User Feedback on Errors:
This is the most critical missing piece - users need clear, immediate feedback:
function displayErrors(errors) {
// Clear previous errors
document.querySelectorAll('.validation-error').forEach(el => el.remove());
document.querySelectorAll('.error-highlight').forEach(el => {
el.classList.remove('error-highlight');
});
// Display new errors
errors.forEach(error => {
error.field.classList.add('error-highlight');
const errorDiv = document.createElement('div');
errorDiv.className = 'validation-error';
errorDiv.textContent = error.message;
errorDiv.style.color = 'red';
errorDiv.style.fontSize = '12px';
errorDiv.style.marginTop = '4px';
error.field.parentNode.insertBefore(errorDiv, error.field.nextSibling);
});
// Scroll to first error
if (errors.length > 0) {
errors[0].field.scrollIntoView({behavior: 'smooth', block: 'center'});
errors[0].field.focus();
}
}
Add these CSS styles for error highlighting:
.error-highlight {
border: 2px solid #d32f2f !important;
background-color: #ffebee !important;
}
.validation-error {
animation: fadeIn 0.3s;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
Complete Implementation:
- Initialize validation on page load:
(function() {
'use strict';
function initValidation() {
const form = document.querySelector('#partner-form');
if (!form) return;
form.addEventListener('submit', validateForm, true);
// Add real-time validation on blur
const fields = form.querySelectorAll('input, select, textarea');
fields.forEach(field => {
field.addEventListener('blur', function() {
validateField(this);
});
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initValidation);
} else {
initValidation();
}
})();
- Add individual field validation for immediate feedback:
function validateField(field) {
// Clear previous error for this field
const existingError = field.parentNode.querySelector('.validation-error');
if (existingError) existingError.remove();
field.classList.remove('error-highlight');
let error = null;
if (field.hasAttribute('required') && !field.value.trim()) {
error = 'This field is required';
} else if (field.type === 'email' && !validateEmail(field.value)) {
error = 'Invalid email format';
}
if (error) {
displayErrors([{field: field, message: error}]);
}
}
Testing Checklist:
- Test with empty required fields
- Test with invalid email formats
- Test form submission with JavaScript disabled (server-side validation should catch it)
- Test on mobile devices for proper error display
- Verify error messages are accessible (screen readers)
The root cause is that zs-2021’s partner portal uses custom form handling that requires specific event interception. Standard submit event listeners run too late in the submission pipeline. By combining event capturing, AJAX interception, and comprehensive user feedback, you’ll prevent invalid data from entering your partner database while providing a smooth user experience.
After implementing these changes, your data quality issues should be resolved, and partners will receive clear guidance on form completion requirements.