Here’s a comprehensive solution that addresses all three aspects - bundle selection validation, error handling, and UI feedback.
First, use MutationObserver to detect when bundle options are dynamically loaded:
const observer = new MutationObserver(() => {
const bundleContainer = document.querySelector('.bundle-options');
if (bundleContainer) validateBundleReady();
});
observer.observe(document.body, {childList: true, subtree: true});
For the validation itself, implement a comprehensive check that waits for all bundle components:
function validateBundle() {
const required = document.querySelectorAll('[data-bundle-required="true"]');
const missing = Array.from(required).filter(item => !item.checked);
return {valid: missing.length === 0, missing};
}
For UI feedback, create an error display system that shows specific missing items:
function showValidationError(missingItems) {
const errorDiv = document.getElementById('bundle-validation-error');
errorDiv.innerHTML = `<strong>Missing required bundle items:</strong><ul>${missingItems.map(item => `<li>${item.dataset.itemName}</li>`).join('')}</ul>`;
errorDiv.setAttribute('role', 'alert');
}
The key is handling the timing issue with MutationObserver instead of relying on fixed delays or load events. This ensures your validation always runs after HubSpot has finished rendering the bundle options. Wrap your form submission handler to prevent invalid quotes from being created:
form.addEventListener('submit', (e) => {
const validation = validateBundle();
if (!validation.valid) {
e.preventDefault();
showValidationError(validation.missing);
}
});
This approach solves the null reference errors by waiting for actual DOM presence, provides clear error messaging to users, and prevents incomplete bundles from being submitted. Make sure to test with different bundle configurations, especially when products are added or removed dynamically during quote creation.