Add user displayed completion tracking to your Collapsible Sections
Using a lightweight JavaScript snippet that does just that. The script monitors each collapsible section and checks whether all visible fields within that section have been filled out. If they are, the section is marked as “complete” with a visual indicator.
Now, a quick note: this isn’t performing any advanced form validation — it’s not checking for correct formats or required fields. It simply looks for whether each visible field in the section has a value. Once they do, the section gets flagged as completed.
It’s a simple, user-friendly way to help guide users through long forms by giving them a sense of progress as they go.
Add the tracking JavaScript
Add the below JavaScript to your form using the Code Chest plugin. This JavaScript code snippet does all the heavy lifting we’ll need. So just copy and paste it over to your form code chest and you’re good to go!
const CS_CHECK_ONLY_REQUIRED_FIELDS = true;
const checkCollapsibleSectionComplete = (sectionBody) => {
const sectionComplete = ( sectionBody.querySelectorAll('.-cs-field-check').length === sectionBody.querySelectorAll('.-cs-field-completed').length );
document.getElementById( sectionBody.getAttribute('aria-labelledby') ).classList.toggle('-cs-completed', sectionComplete);
};
const toggleCollapsibleSectionFieldCompleted = (input, completed) => {
input.closest('.gfield').classList.toggle('-cs-field-completed', completed);
checkCollapsibleSectionComplete( input.closest('.collapsible-sections-collapsible-body') );
};
gform.addAction('gf_collapsible_sections_setup', (form_id, current_page, formDomId) => {
const csFormWrap = document.querySelector(`#gform_wrapper_${formDomId}`);
const csFieldsSelector = CS_CHECK_ONLY_REQUIRED_FIELDS ? '.gfield.gfield_contains_required' : '.gfield';
csFormWrap.querySelectorAll(`.collapsible-sections-collapsible-body ${csFieldsSelector}:not(.gfield--type-hidden):not(.gfield--type-html):not(.gfield--type-section)`).forEach(field => {
field.classList.add('-cs-field-check');
});
// text based inputs
csFormWrap.querySelectorAll(`.-cs-field-check textarea, .-cs-field-check input:not([type="checkbox"]:not([type="radio"]:not([type="hidden"])`).forEach(input => {
['change', 'keyup', 'blur'].forEach(eventName => {
input.addEventListener(eventName, (e) => {
const fieldCompleted = ( e.currentTarget.value !== '' );
toggleCollapsibleSectionFieldCompleted( e.currentTarget, fieldCompleted );
});
input.dispatchEvent(new Event(eventName));
});
});
// radio / checkbox based inputs
csFormWrap.querySelectorAll(`.-cs-field-check input[type="radio"], .-cs-field-check input[type="checkbox"]`).forEach(input => {
input.addEventListener('change', (e) => {
const fieldCompleted = ( e.currentTarget.checked || e.currentTarget.closest('.ginput_container').querySelectorAll('input:checked').length );
toggleCollapsibleSectionFieldCompleted( e.currentTarget, fieldCompleted );
});
input.dispatchEvent(new Event('change'));
});
// selects
csFormWrap.querySelectorAll(`.-cs-field-check select`).forEach(select => {
select.addEventListener('change', (e) => {
const fieldCompleted = ( e.currentTarget.value !== '' );
toggleCollapsibleSectionFieldCompleted( e.currentTarget, fieldCompleted );
});
select.dispatchEvent(new Event('change'));
});
// signature field input
csFormWrap.querySelectorAll(`.-cs-field-check.gfield--type-signature input[name$="_data"]`).forEach(input => {
input.addEventListener('change', (e) => {
const fieldCompleted = ( e.currentTarget.value !== '' );
toggleCollapsibleSectionFieldCompleted( e.currentTarget, fieldCompleted );
});
input.lastValue = input.value;
clearInterval(input.pollChanges);
input.pollChanges = setInterval(() => {
if ( input.value !== input.lastValue ) {
input.lastValue = input.value;
input.dispatchEvent(new Event('change'));
}
}, 200);
input.dispatchEvent(new Event('change'));
});
});
Add the CSS
Once you’ve added the JavaScript tracking snippet from above, add one of the example CSS snippets to get the style and checkmark layout that works for you. See the examples below and corresponding CSS snippets to copy and paste.
This CSS design example positions the complete check mark inline to the left of the section title. Makes for an easy and clean way to tell what a user has completed. Updated the colours below to customise it even further. Fill out some details in the demo below to see it in action.
.collapsible-sections-field.-cs-completed:not(.collapsible-sections-section-error):before {
content: "✓";
width: 20px;
height: 20px;
overflow: hidden;
position: absolute;
left: 20px;
top: 50%;
background-color: #2cc9b6;
color: white;
border-radius: 100px;
line-height: 20px;
font-size: 16px;
text-align: center;
transform: translateY(-50%);
padding: 16px;
display: flex;
justify-content: center;
align-items: center;
}
[class*=cs-theme--] .gsection.collapsible-sections-field.-cs-completed:not(.collapsible-sections-section-error) {
--cs-background-color: #e1fdf9;
--cs-border-color: #00b295;
padding-left: 70px !important;
}