Volunteer Registration Form

Download our latest schedule and never miss out!

    Step 1 of 6

    Section 1

    Personal Information

    We're so thrilled you're here. Whether you're a student, professional, coach, creator, organiser, or someone with a big heart for community, there's a place for you in our journey. Your responses will help us match you with the best volunteering opportunities, while making sure you feel supported, safe, and seen. Just take your time — we're excited to learn more about you!

    Accepted formats: JPG, PNG, PDF. Maximum size: 2 MB.
    document.addEventListener('DOMContentLoaded', function () { var TOTAL_STEPS = 6; var currentStep = 0; /* ── Step navigation ──────────────────────────────────────── */ function showStep(idx) { for (var i = 0; i < TOTAL_STEPS; i++) { var el = document.getElementById('vol-step-' + i); if (el) el.style.display = (i === idx) ? 'block' : 'none'; } currentStep = idx; updateProgress(idx); window.scrollTo({ top: 0, behavior: 'smooth' }); } function updateProgress(idx) { var pct = ((idx + 1) / TOTAL_STEPS) * 100; var fill = document.getElementById('vol-progress-fill'); var text = document.getElementById('vol-progress-text'); if (fill) fill.style.width = pct + '%'; if (text) text.textContent = 'Step ' + (idx + 1) + ' of ' + TOTAL_STEPS; } /* ── Per-step validation with specific missing-field reporting ─ */ /* Field label map: CF7 name → human-readable label */ var FIELD_LABELS = { 'full-name': 'Full Name', 'short-name': 'Preferred Short Name', 'ic': 'Identification Number', 'age': 'Age', 'dob': 'Date of Birth', 'phone': 'Mobile Number', 'email': 'Email Address', 'Occupation': 'Occupation', 'home-address': 'Home Address', 'communication-method': 'Preferred Method of Communication', 'spoken-language': 'Spoken Language(s)', 'spoken-language-other': 'Spoken Language — please specify "Others"', 'emergency-contact-name': 'Emergency Contact Name', 'emergency-relationship': 'Relationship to You', 'emergency-phone': 'Emergency Contact Phone Number', 'motivation': 'What motivates you to join? (Q19)', 'contribution-areas': 'Areas you can contribute to (Q20)', 'skill-development': 'Skill areas to develop (Q21)', 'volunteer-location': 'Preferred Volunteer Location', 'availability-weekdays': 'Weekday Availability', 'availability-saturday': 'Saturday Availability', 'availability-sunday': 'Sunday Availability', 'start-date': 'Preferred Start Date', 'end-date': 'Preferred End Date', 'commitment-duration': 'Duration of Commitment', 'number-of-hours': 'Hours per Week', 'platform-know-programme': 'How did you hear about us?', 'platform-other': 'How did you hear about us? — please specify "Others"', 'areas-of-interest': 'Areas of Interest (Q33)', 'areas-of-interest-other': 'Areas of Interest — please specify "Others"', 'privacy-acknowledgement': 'Privacy Statement — please tick to accept', 'commitment-acknowledgement': 'Gaining Commitment — please tick to accept', 'indemnity-acknowledgement': 'General Indemnity — please tick to accept' }; /* Scroll to and focus a field, then flash its border red briefly */ function focusField(name) { /* Try direct name selector first, then name[] variant */ var el = document.querySelector('[name="' + name + '"]') || document.querySelector('[name="' + name + '[]"]'); if (!el) return; /* For checkboxes/radios scroll to the parent wrapper instead */ var target = (el.type === 'checkbox' || el.type === 'radio') ? (el.closest('.vol-check-col') || el.closest('.vol-radio-row') || el.closest('.vol-radio-col') || el) : el; target.scrollIntoView({ behavior: 'smooth', block: 'center' }); /* Flash red outline on the actual input / wrapper */ target.classList.add('vol-field-error'); setTimeout(function () { target.classList.remove('vol-field-error'); }, 2200); } /* Build and display the specific error list, or hide it if clean */ function showErrors(stepIdx, missing) { var errEl = document.getElementById('step' + stepIdx + '-error'); if (!errEl) return; if (missing.length === 0) { errEl.style.display = 'none'; errEl.innerHTML = ''; return; } var html = '⚠️ Please complete the following before continuing:
      '; missing.forEach(function (name) { var label = FIELD_LABELS[name] || name; html += '
    • ' + label + '
    • '; }); html += '
    '; errEl.innerHTML = html; errEl.style.display = 'block'; /* Wire click handlers on the generated links */ errEl.querySelectorAll('.vol-error-link').forEach(function (link) { link.addEventListener('click', function (e) { e.preventDefault(); focusField(this.getAttribute('data-field')); }); }); } function validateStep(stepIdx) { var missing = []; /* Is a text / number / date / select input filled? */ function filled(name) { var el = document.querySelector('[name="' + name + '"]'); return el && el.value.trim() !== ''; } /* Does a checkbox group have at least one option ticked? CF7 may render the name as "name" or "name[]" — check both. */ function checkboxAnswered(name) { var sel = 'input[type="checkbox"][name="' + name + '"]:checked,' + 'input[type="checkbox"][name="' + name + '[]"]:checked'; return document.querySelectorAll(sel).length > 0; } /* Collect missing rather than just flagging ok = false */ function require(name, check) { if (!check) missing.push(name); } if (stepIdx === 0) { require('full-name', filled('full-name')); require('short-name', filled('short-name')); require('ic', filled('ic')); require('age', filled('age')); require('dob', filled('dob')); /* gender & nationality: always answered via default:1 — no check needed */ /* image-upload: validated server-side by CF7 */ } if (stepIdx === 1) { require('phone', filled('phone')); require('email', filled('email')); require('Occupation', filled('Occupation')); require('home-address', filled('home-address')); require('communication-method', checkboxAnswered('communication-method')); require('spoken-language', checkboxAnswered('spoken-language')); /* If "Others" ticked for spoken language, the specify field is required */ var spokenOthers = document.querySelectorAll( 'input[type="checkbox"][name="spoken-language"][value="Others"]:checked,' + 'input[type="checkbox"][name="spoken-language[]"][value="Others"]:checked' ); if (spokenOthers.length > 0) require('spoken-language-other', filled('spoken-language-other')); } if (stepIdx === 2) { require('emergency-contact-name', filled('emergency-contact-name')); require('emergency-relationship', filled('emergency-relationship')); require('emergency-phone', filled('emergency-phone')); } if (stepIdx === 3) { require('motivation', checkboxAnswered('motivation')); require('contribution-areas', checkboxAnswered('contribution-areas')); require('skill-development', checkboxAnswered('skill-development')); require('availability-weekdays', checkboxAnswered('availability-weekdays')); require('availability-saturday', checkboxAnswered('availability-saturday')); require('availability-sunday', checkboxAnswered('availability-sunday')); require('number-of-hours', checkboxAnswered('number-of-hours')); require('volunteer-location', filled('volunteer-location')); require('commitment-duration', filled('commitment-duration')); require('start-date', filled('start-date')); require('end-date', filled('end-date')); require('platform-know-programme', filled('platform-know-programme')); /* past-experience: always answered via default:1 — no check needed */ /* If "Others" selected for heard-about-us, the specify field is required */ var platformEl = document.getElementById('platform-know-programme'); if (platformEl && platformEl.value === 'Others') { require('platform-other', filled('platform-other')); } } if (stepIdx === 4) { require('areas-of-interest', checkboxAnswered('areas-of-interest')); /* If "Others" ticked for areas of interest, the specify field is required */ var aoiOthers = document.querySelectorAll( 'input[type="checkbox"][name="areas-of-interest"][value="Others"]:checked,' + 'input[type="checkbox"][name="areas-of-interest[]"][value="Others"]:checked' ); if (aoiOthers.length > 0) require('areas-of-interest-other', filled('areas-of-interest-other')); } if (stepIdx === 5) { ['privacy-acknowledgement', 'commitment-acknowledgement', 'indemnity-acknowledgement'].forEach(function (n) { var el = document.querySelector('input[name="' + n + '"]'); require(n, el && el.checked); }); } showErrors(stepIdx, missing); return missing.length === 0; } /* ── Wire Next buttons ────────────────────────────────────── */ document.querySelectorAll('.vol-btn-next').forEach(function (btn) { btn.addEventListener('click', function () { var step = parseInt(this.getAttribute('data-step'), 10); if (!validateStep(step)) return; if (currentStep 0) showStep(currentStep - 1); }); }); /* ── Block CF7 submit if final step is invalid ────────────── */ var cf7Form = document.querySelector('.wpcf7-form'); if (cf7Form) { cf7Form.addEventListener('submit', function (e) { if (!validateStep(5)) { e.preventDefault(); e.stopPropagation(); } }, true); } /* ── Highlight selected radio / checkbox list items ──────── */ function syncListItemState(input) { var item = input.closest('.wpcf7-list-item'); if (!item) return; if (input.type === 'radio') { document.querySelectorAll('input[type="radio"][name="' + input.name + '"]').forEach(function (r) { var li = r.closest('.wpcf7-list-item'); if (li) li.classList.toggle('is-checked', r.checked); }); } else if (input.type === 'checkbox') { item.classList.toggle('is-checked', input.checked); } } document.addEventListener('change', function (e) { var t = e.target; if (t && (t.type === 'radio' || t.type === 'checkbox')) syncListItemState(t); }); /* Sync initial state for any pre-checked inputs (e.g. default:1 radios) */ document.querySelectorAll( '.vol-radio-col input[type="radio"], .vol-radio-row input[type="radio"], .vol-check-col input[type="checkbox"]' ).forEach(syncListItemState); /* ── Clear error banners on successful CF7 submit ─────────── */ document.addEventListener('wpcf7submit', function () { for (var i = 0; i < TOTAL_STEPS; i++) { var err = document.getElementById('step' + i + '-error'); if (err) { err.style.display = 'none'; err.innerHTML = ''; } } }, false); /* ── Conditional reveal: Q32 "Where did you hear" → Others ── */ var platformSelect = document.getElementById('platform-know-programme'); var platformOtherWrap = document.getElementById('platform-other-wrap'); if (platformSelect && platformOtherWrap) { platformSelect.addEventListener('change', function () { var show = this.value === 'Others'; platformOtherWrap.style.display = show ? 'block' : 'none'; if (!show) { var inp = document.getElementById('platform-other'); if (inp) inp.value = ''; } }); } /* ── Conditional reveals: checkbox "Others" sub-fields ────── Covers Q14 (Spoken Language) and Q33 (Areas of Interest) */ document.addEventListener('change', function (e) { var t = e.target; if (!t || t.type !== 'checkbox' || t.value !== 'Others') return; var name = t.name.replace('[]', ''); if (name === 'spoken-language') { var wrap = document.getElementById('spoken-other-wrap'); var inp = document.getElementById('spoken-language-other'); if (wrap) wrap.style.display = t.checked ? 'block' : 'none'; if (!t.checked && inp) inp.value = ''; } if (name === 'areas-of-interest') { var wrap = document.getElementById('aoi-other-wrap'); var inp = document.getElementById('areas-of-interest-other'); if (wrap) wrap.style.display = t.checked ? 'block' : 'none'; if (!t.checked && inp) inp.value = ''; } }); document.querySelectorAll('.vol-bold-key .wpcf7-list-item label').forEach(function (label) { var input = label.querySelector('input'); var textNode = null; label.childNodes.forEach(function (node) { if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== '') { textNode = node; } }); var spanNode = label.querySelector('span:not(.wpcf7-list-item-label)') || label.querySelector('span'); var target = textNode || spanNode; if (!target) return; var raw = target.textContent || target.innerText || ''; var sep = ' \u2014 '; var idx = raw.indexOf(sep); if (idx === -1) return; var keyword = raw.slice(0, idx); var rest = raw.slice(idx); var b = document.createElement('b'); b.textContent = keyword; var tail = document.createTextNode(rest); if (textNode) { label.replaceChild(tail, textNode); label.insertBefore(b, tail); } else if (spanNode) { spanNode.innerHTML = ''; spanNode.appendChild(b); spanNode.appendChild(document.createTextNode(rest)); } }); /* ── Initialise ───────────────────────────────────────────── */ showStep(0); });
    Shopping Cart