Weekly Programmes

Our programmes blend fun, movement, and music to nurture confidence, communication, and leadership in every child.

FunXercise Registration Form

The essential information you share helps us support your child better to create a safe and empowering experience.  

    1 -> 2 -> 3 -> 4 (5 steps) Returning : Step 0 -> 2.5 -> 3 -> 4 (4 steps) One-Off : ONE-OFF PLACEHOLDER ============================================================ -->

    Step 1 of 5

    Step 1

    Let's Get Started

    Please select your registration type, your preferred programme plan, and your session date(s).

    Q1. Type of Registration *

    Please select the option that best describes you.

    condensed single-step form -> Step 4. For now this card is visible but treated as New Registration. -->
    document.addEventListener('DOMContentLoaded', function () { /* ============================================================ ROUTE DEFINITIONS New Registration : Step 0 -> 1 -> 2 -> 3 -> 4 ("Step X of 5") Returning : Step 0 -> 25 -> 3 -> 4 ("Step X of 4") One-Off : ONE-OFF PLACEHOLDER ============================================================ */ var ROUTES = { 'New Registration': { steps: [0, 1, 2, 3, 4], total: 5 }, 'Returning Registration': { steps: [0, 25, 3, 4], total: 4 }, 'One-Off Registration': { steps: [0, 1, 2, 3, 4], total: 5 } }; var ALL_DOM_STEPS = [0, 1, 2, 25, 3, 4]; var currentDomStep = 0; var registrationType = ''; var selectedPlan = null; var selectedLevel = ''; var hasReport = false; /* ============================================================ STEP DISPLAY + PROGRESS BAR ============================================================ */ function getRoute() { return ROUTES[registrationType] || ROUTES['New Registration']; } function showStep(domStepId) { currentDomStep = domStepId; ALL_DOM_STEPS.forEach(function (id) { var el = document.getElementById('fx-step-' + id); if (el) el.style.display = (id === domStepId) ? 'block' : 'none'; }); updateProgress(domStepId); window.scrollTo({ top: 0, behavior: 'smooth' }); } function updateProgress(domStepId) { var route = getRoute(); var pos = route.steps.indexOf(domStepId); if (pos < 0) pos = 0; var humanPos = pos + 1; var total = route.total; var pct = (humanPos / total) * 100; var fill = document.getElementById('fx-progress-fill'); var text = document.getElementById('fx-progress-text'); if (fill) fill.style.width = pct + '%'; if (text) text.textContent = 'Step ' + humanPos + ' of ' + total; } function goNext() { var route = getRoute(); var pos = route.steps.indexOf(currentDomStep); if (pos 0) showStep(route.steps[pos - 1]); } /* ============================================================ REGISTRATION TYPE CARDS ============================================================ */ document.querySelectorAll('input[name="registration-type"]').forEach(function (radio) { radio.addEventListener('change', function () { registrationType = this.value; document.getElementById('fx-reg-type').value = registrationType; var planSection = document.getElementById('fx-plan-section'); var sessionSection = document.getElementById('fx-session-section'); if (planSection) planSection.style.display = 'block'; if (selectedPlan && sessionSection) sessionSection.style.display = 'block'; /* Lookup is triggered manually by the user via the "Look Up My Records" button on Step 2.5 */ }); }); /* ============================================================ PLAN CARDS Update plan names and pricing as directed by management ============================================================ */ var PLANS = { 'Single Session': { sessions: 1, price: 'RM 30' }, 'Bundle (3 Sessions)': { sessions: 3, price: 'RM 75' }, 'Group Bundle': { sessions: 3, price: 'RM 300' } }; document.querySelectorAll('input[name="plan-selection"]').forEach(function (radio) { radio.addEventListener('change', function () { selectedPlan = this.value; document.getElementById('fx-selected-plan').value = selectedPlan; var plan = PLANS[selectedPlan]; if (plan) { document.getElementById('fx-session-count').value = plan.sessions; buildDatePickers(plan.sessions); var ss = document.getElementById('fx-session-section'); if (ss) ss.style.display = 'block'; updatePaymentSummary(); } }); }); /* ============================================================ DATE PICKERS AMEND according to programme calendar provided by Team Lead / Supervisor / Manager. ============================================================ */ function buildDatePickers(count) { var wrapper = document.getElementById('fx-dates-wrapper'); if (!wrapper) return; wrapper.innerHTML = ''; for (var i = 0; i < count; i++) { var lbl = count === 1 ? 'Session Date' : ordinalLabel(i + 1) + ' Session Date'; var fieldName = 'session-date-' + (i + 1); var wrap = document.createElement('div'); wrap.className = 'fx-date-picker-wrap'; wrap.innerHTML = '' + ''; wrapper.appendChild(wrap); } } function ordinalLabel(n) { var sfx = ['th','st','nd','rd']; var v = n % 100; return n + (sfx[(v - 20) % 10] || sfx[v] || sfx[0]); } /* ============================================================ RETURNING REGISTRATION — REAL FETCH LOGIC Calls the WPCode PHP snippet via wp_ajax endpoint. Nonce is injected by PHP into window.c2rAjax automatically. ============================================================ */ /* Internal state for sibling flow */ var returningEmail = ''; function initiateReturningLookup() { /* Read email from the returning email input field (injected into Step 2.5 HTML — see fx-ret-email-wrap) */ var emailInput = document.getElementById('fx-ret-email-input'); if (!emailInput || !emailInput.value.trim()) { showReturningError('Please enter your email address to look up your records.'); return; } var email = emailInput.value.trim(); if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { showReturningError('Please enter a valid email address.'); return; } returningEmail = email; hideReturningError(); showReturningLoading(true); /* Check c2rAjax is available (WPCode snippet must be active) */ if (typeof window.c2rAjax === 'undefined') { showReturningLoading(false); showReturningError('Lookup service is not available. Please contact us directly at hello@care2run.my.'); return; } fetch(window.c2rAjax.ajaxurl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ action: 'c2r_returning_user_lookup', nonce: window.c2rAjax.nonce, email: email }) }) .then(function (r) { return r.json(); }) .then(function (res) { showReturningLoading(false); if (!res.success) { /* rate_limited, nonce fail, server error */ var msg = (res.data && res.data.message) ? res.data.message : 'An unexpected error occurred. Please try again or contact us at hello@care2run.my.'; showReturningError(msg); return; } var payload = res.data; if (payload.state === 'multiple') { /* Siblings found — show dropdown for selection */ showSiblingDropdown(payload.siblings, payload.message); } else if (payload.state === 'full') { applyReturningState('full', payload.data); } else if (payload.state === 'partial') { applyReturningState('partial', payload.data); } else { /* not_found */ applyReturningState('not_found', {}); } }) .catch(function () { showReturningLoading(false); showReturningError('Could not connect to the lookup service. Please check your internet connection and try again.'); }); } /* Called when user selects a child from the sibling dropdown */ function fetchByEntryId(entryId) { showReturningLoading(true); hideSiblingDropdown(); fetch(window.c2rAjax.ajaxurl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ action: 'c2r_returning_user_fetch', nonce: window.c2rAjax.nonce, entry_id: entryId }) }) .then(function (r) { return r.json(); }) .then(function (res) { showReturningLoading(false); if (!res.success) { var msg = (res.data && res.data.message) ? res.data.message : 'Could not retrieve this record.'; showReturningError(msg); return; } var payload = res.data; if (payload.state === 'full') applyReturningState('full', payload.data); else if (payload.state === 'partial') applyReturningState('partial', payload.data); else applyReturningState('not_found', {}); }) .catch(function () { showReturningLoading(false); showReturningError('Could not retrieve this record. Please try again.'); }); } /* Populate blue or yellow panel with retrieved data */ function applyReturningState(state, data) { var blue = document.getElementById('fx-ret-blue'); var yellow = document.getElementById('fx-ret-yellow'); var red = document.getElementById('fx-ret-red'); if (blue) blue.style.display = 'none'; if (yellow) yellow.style.display = 'none'; if (red) red.style.display = 'none'; hideSiblingDropdown(); function val(v) { return (v && v.trim()) ? v.trim() : '—'; } if (state === 'full') { if (blue) { blue.style.display = 'block'; document.getElementById('ret-participant-name').textContent = val(data.participant_name); document.getElementById('ret-contact').textContent = val(data.contact); document.getElementById('ret-age').textContent = val(data.age); document.getElementById('ret-parent-name').textContent = val(data.parent_name); document.getElementById('ret-parent-contact').textContent = val(data.parent_contact); document.getElementById('ret-parent-email').textContent = val(data.parent_email); document.getElementById('ret-emergency-name').textContent = val(data.emergency_name); document.getElementById('ret-emergency-contact').textContent = val(data.emergency_contact); document.getElementById('ret-emergency-email').textContent = val(data.emergency_email); } } else if (state === 'partial') { if (yellow) { yellow.style.display = 'block'; document.getElementById('ret-p-participant-name').textContent = val(data.participant_name); document.getElementById('ret-p-contact').textContent = val(data.contact); document.getElementById('ret-p-age').textContent = val(data.age); document.getElementById('ret-p-parent-name').textContent = val(data.parent_name); document.getElementById('ret-p-parent-contact').textContent = val(data.parent_contact); document.getElementById('ret-p-parent-email').textContent = val(data.parent_email); document.getElementById('ret-p-emergency-name').textContent = val(data.emergency_name); document.getElementById('ret-p-emergency-contact').textContent = val(data.emergency_contact); document.getElementById('ret-p-emergency-email').textContent = val(data.emergency_email); } } else { /* not_found */ if (red) red.style.display = 'block'; } } /* Show inline sibling selection dropdown */ function showSiblingDropdown(siblings, message) { var box = document.getElementById('fx-ret-sibling-box'); if (!box) return; var html = '

    ' + (message || 'We found more than one registration under this email. Please select the child you are registering for.') + '

    ' + '' + '-- Select a child --'; siblings.forEach(function (s) { html += '' + s.child_name + ' (submitted ' + s.submitted + ')' + ''; }); html += '' + ''; box.innerHTML = html; box.style.display = 'block'; document.getElementById('fx-ret-sibling-btn').addEventListener('click', function () { var sel = document.getElementById('fx-ret-sibling-select'); if (!sel || !sel.value) { showReturningError('Please select a child from the list first.'); return; } fetchByEntryId(parseInt(sel.value, 10)); }); } function hideSiblingDropdown() { var box = document.getElementById('fx-ret-sibling-box'); if (box) { box.innerHTML = ''; box.style.display = 'none'; } } /* Loading spinner shown during fetch */ function showReturningLoading(show) { var loader = document.getElementById('fx-ret-loading'); if (loader) loader.style.display = show ? 'block' : 'none'; } /* Inline error message within the returning panel */ function showReturningError(msg) { var err = document.getElementById('fx-ret-error'); if (err) { err.textContent = '⚠️ ' + msg; err.style.display = 'block'; } } function hideReturningError() { var err = document.getElementById('fx-ret-error'); if (err) err.style.display = 'none'; } /* Wire the Look Up button in Step 2.5 */ var lookupBtn = document.getElementById('fx-ret-lookup-btn'); if (lookupBtn) { lookupBtn.addEventListener('click', function () { initiateReturningLookup(); }); } /* Also allow Enter key in email field to trigger lookup */ var emailInput = document.getElementById('fx-ret-email-input'); if (emailInput) { emailInput.addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); initiateReturningLookup(); } }); } /* ============================================================ PAYMENT SUMMARY ============================================================ */ function updatePaymentSummary() { var display = document.getElementById('fx-payment-plan-display'); if (!display || !selectedPlan) return; var plan = PLANS[selectedPlan]; if (!plan) return; display.innerHTML = '' + selectedPlan + ' — ' + plan.sessions + ' session(s) — ' + plan.price + ''; } /* ============================================================ PAYMENT METHOD TOGGLE ============================================================ */ document.querySelectorAll('input[name="payment-method"]').forEach(function (radio) { radio.addEventListener('change', function () { var qr = document.getElementById('fx-qr-area'); var bk = document.getElementById('fx-bank-area'); if (this.value === 'QR Code') { if (qr) qr.style.display = 'block'; if (bk) bk.style.display = 'none'; } else { if (qr) qr.style.display = 'none'; if (bk) bk.style.display = 'block'; } }); }); /* ============================================================ SECTION B — REPORT TOGGLE + L1/L2/L3 BRANCHING ============================================================ */ function setupReportToggle() { document.querySelectorAll('input[name="has-report"]').forEach(function (r) { r.addEventListener('change', handleReportChange); }); } function handleReportChange() { var checked = document.querySelector('input[name="has-report"]:checked'); var uploadBox = document.getElementById('fx-report-upload-box'); var levelSec = document.getElementById('fx-support-level-section'); var l1 = document.getElementById('fx-step-b-l1'); var l23 = document.getElementById('fx-step-b-l23'); if (!checked) return; hasReport = checked.value.indexOf('Yes') === 0; if (uploadBox) uploadBox.style.display = hasReport ? 'block' : 'none'; if (levelSec) levelSec.style.display = hasReport ? 'none' : 'block'; if (hasReport) { if (l1) l1.style.display = 'none'; if (l23) l23.style.display = 'none'; toggleLevelFields(''); } else { handleLevelChange(); } } function handleLevelChange() { var l1 = document.getElementById('fx-step-b-l1'); var l23 = document.getElementById('fx-step-b-l23'); if (selectedLevel === 'L1') { if (l1) l1.style.display = 'block'; if (l23) l23.style.display = 'none'; toggleLevelFields('L1'); } else if (selectedLevel === 'L2' || selectedLevel === 'L3') { if (l1) l1.style.display = 'none'; if (l23) l23.style.display = 'block'; toggleLevelFields('L23'); } else { if (l1) l1.style.display = 'none'; if (l23) l23.style.display = 'none'; toggleLevelFields(''); } } function toggleLevelFields(active) { var l1Fields = document.querySelectorAll('#fx-step-b-l1 input, #fx-step-b-l1 textarea, #fx-step-b-l1 select'); var l23Fields = document.querySelectorAll('#fx-step-b-l23 input, #fx-step-b-l23 textarea, #fx-step-b-l23 select'); l1Fields.forEach(function (el) { el.disabled = (active !== 'L1'); }); l23Fields.forEach(function (el) { el.disabled = (active !== 'L23'); }); } document.querySelectorAll('input[name="support-level"]').forEach(function (radio) { radio.addEventListener('change', function () { selectedLevel = this.value; document.getElementById('fx-support-level').value = selectedLevel; handleLevelChange(); }); }); setupReportToggle(); /* ============================================================ OTHERS TOGGLE HELPERS ============================================================ */ function setupOthersToggle(checkboxName, boxId) { var els = document.querySelectorAll('[name="' + checkboxName + '[]"], [name="' + checkboxName + '"]'); function check() { var found = false; els.forEach(function (cb) { if (cb.value && cb.value.trim() === 'Others' && cb.checked) found = true; }); var box = document.getElementById(boxId); if (box) box.style.display = found ? 'block' : 'none'; } els.forEach(function (cb) { cb.addEventListener('change', check); }); check(); } setupOthersToggle('l1-diagnosed', 'l1-diagnosed-other-box'); setupOthersToggle('l1-traits', 'l1-traits-other-box'); setupOthersToggle('l1-comm-mode', 'l1-comm-other-box'); setupOthersToggle('l1-motivation', 'l1-motivation-other-box'); setupOthersToggle('l23-diagnosed', 'l23-diagnosed-other-box'); setupOthersToggle('l23-traits', 'l23-traits-other-box'); setupOthersToggle('l23-comm-mode', 'l23-comm-other-box'); setupOthersToggle('l23-comm-aids', 'l23-comm-aids-other-box'); setupOthersToggle('l23-motivation', 'l23-motivation-other-box'); setupOthersToggle('hear-about', 'hear-about-other-box'); setupOthersToggle('connect-future', 'connect-future-other-box'); /* ============================================================ FIELD ERROR HELPERS ============================================================ */ function showErr(id, show) { var el = document.getElementById(id); if (el) el.style.display = show ? 'block' : 'none'; } function scrollToFirstError() { var first = document.querySelector('.fx-field-error[style*="block"], .fx-error[style*="block"]'); if (first) first.scrollIntoView({ behavior: 'smooth', block: 'center' }); } /* ============================================================ VALIDATION — STEP 0 ============================================================ */ function validateStep0() { var ok = true; var regType = document.querySelector('input[name="registration-type"]:checked'); showErr('err-reg-type', !regType); if (!regType) ok = false; var plan = document.querySelector('input[name="plan-selection"]:checked'); showErr('err-plan', !plan); if (!plan) ok = false; var firstDate = document.getElementById('session-date-1'); var dateEmpty = !firstDate || !firstDate.value; showErr('err-session-date', dateEmpty); if (dateEmpty) ok = false; return ok; } /* ============================================================ VALIDATION — STEP 1 (Section A) ============================================================ */ function validateStep1() { var ok = true; var fields = [ ['child-fullname', 'err-child-fullname'], ['child-nickname', 'err-child-nickname'], ['child-dob', 'err-child-dob'], ['child-age', 'err-child-age'], ['mother-fullname', 'err-mother-fullname'], ['mother-nickname', 'err-mother-nickname'], ['mother-email', 'err-mother-email'], ['mother-mobile', 'err-mother-mobile'], ['mother-ic', 'err-mother-ic'], ['emergency-name', 'err-emergency-name'], ['emergency-mobile', 'err-emergency-mobile'], ['emergency-email', 'err-emergency-email'] ]; fields.forEach(function (f) { var el = document.querySelector('[name="' + f[0] + '"]'); var empty = !el || !el.value.trim(); showErr(f[1], empty); if (empty) ok = false; }); var gender = document.querySelector('input[name="child-gender"]:checked'); showErr('err-child-gender', !gender); if (!gender) ok = false; var nat = document.querySelector('select[name="child-nationality"]'); showErr('err-child-nationality', !nat || !nat.value); if (!nat || !nat.value) ok = false; var kt = document.querySelector('select[name="kids-tshirt"]'); showErr('err-kids-tshirt', !kt || !kt.value); if (!kt || !kt.value) ok = false; var mt = document.querySelector('select[name="mother-tshirt"]'); showErr('err-mother-tshirt', !mt || !mt.value); if (!mt || !mt.value) ok = false; var ma = document.querySelector('input[name="mother-accompany"]:checked'); showErr('err-mother-accompany', !ma); if (!ma) ok = false; return ok; } /* ============================================================ VALIDATION — STEP 2 (Section B) ============================================================ */ function validateStep2() { var ok = true; var fs = document.querySelector('[name="favourite-sports"]'); showErr('err-favourite-sports', !fs || !fs.value.trim()); if (!fs || !fs.value.trim()) ok = false; var al = document.querySelector('select[name="activity-level"]'); showErr('err-activity-level', !al || !al.value); if (!al || !al.value) ok = false; var gi = document.querySelector('select[name="guardian-involvement"]'); showErr('err-guardian-involvement', !gi || !gi.value); if (!gi || !gi.value) ok = false; var rep = document.querySelector('input[name="has-report"]:checked'); var repInvalid = !rep; showErr('err-has-report', repInvalid); if (repInvalid) { ok = false; } else if (!hasReport && !selectedLevel) { showErr('err-support-level', true); ok = false; } else { showErr('err-support-level', false); } return ok; } /* ============================================================ VALIDATION — STEP 2.5 (Returning Review) Blocks if red state — user must go back. ============================================================ */ function validateStep25() { var blue = document.getElementById('fx-ret-blue'); var yellow = document.getElementById('fx-ret-yellow'); var red = document.getElementById('fx-ret-red'); var siblingBox = document.getElementById('fx-ret-sibling-box'); var errBox = document.getElementById('fx-ret-step25-error'); function showStep25Err(msg) { if (errBox) { errBox.textContent = '⚠️ ' + msg; errBox.style.display = 'block'; } } function hideStep25Err() { if (errBox) errBox.style.display = 'none'; } // Check 1: User has not clicked Look Up at all // None of the panels are visible and sibling box is empty var blueVisible = blue && blue.style.display !== 'none'; var yellowVisible = yellow && yellow.style.display !== 'none'; var redVisible = red && red.style.display !== 'none'; var siblingVisible = siblingBox && siblingBox.style.display !== 'none' && siblingBox.innerHTML.trim() !== ''; if (!blueVisible && !yellowVisible && !redVisible && !siblingVisible) { showStep25Err('Please enter your email address and click "Look Up My Records" before continuing.'); return false; } // Check 2: Red panel — no data found, must go back if (redVisible) { showStep25Err('No records were found. Please click Previous and select New Registration.'); return false; } // Check 3: Sibling dropdown is still showing — user has not picked a child yet if (siblingVisible) { var sel = document.getElementById('fx-ret-sibling-select'); if (!sel || !sel.value || sel.value === '') { showStep25Err('We found more than one registration. Please select which child you are registering for before continuing.'); return false; } } // Check 4: Yellow panel — warn but allow to proceed // (user may choose to continue with partial data) hideStep25Err(); return true; } /* ============================================================ VALIDATION — STEP 3 (Policies) ============================================================ */ function validateStep3() { var policies = [ ['policy-health', 'err-policy-health'], ['policy-emergency', 'err-policy-emergency'], ['policy-accompany', 'err-policy-accompany'], ['policy-fees', 'err-policy-fees'], ['policy-photos', 'err-policy-photos'], ['policy-indemnity', 'err-policy-indemnity'] ]; var ok = true; policies.forEach(function (p) { var cb = document.querySelector('input[name="' + p[0] + '"]'); showErr(p[1], !cb || !cb.checked); if (!cb || !cb.checked) ok = false; }); return ok; } /* ============================================================ VALIDATION — STEP 4 (Payment + Stay Connected) ============================================================ */ function validateStep4() { var ok = true; var hear = document.querySelectorAll('input[name="hear-about[]"]:checked, input[name="hear-about"]:checked'); showErr('err-hear-about', hear.length === 0); if (hear.length === 0) ok = false; var conn = document.querySelectorAll('input[name="connect-future[]"]:checked, input[name="connect-future"]:checked'); showErr('err-connect-future', conn.length === 0); if (conn.length === 0) ok = false; var uploaded = document.querySelector('.dnd-upload-status.complete, .codedropz-upload-status.complete'); showErr('err-payment-slip', !uploaded); if (!uploaded) ok = false; return ok; } /* ============================================================ NEXT / PREV BUTTON WIRING ============================================================ */ document.querySelectorAll('.fx-btn-next').forEach(function (btn) { btn.addEventListener('click', function () { var validates = this.getAttribute('data-validates'); var passed = true; if (validates === 'step0') passed = validateStep0(); else if (validates === 'step1') passed = validateStep1(); else if (validates === 'step2') passed = validateStep2(); else if (validates === 'step25') passed = validateStep25(); else if (validates === 'step3') passed = validateStep3(); if (!passed) { scrollToFirstError(); return; } goNext(); }); }); document.querySelectorAll('.fx-btn-prev').forEach(function (btn) { btn.addEventListener('click', function () { goPrev(); }); }); /* ============================================================ CF7 SUBMIT GUARD All Step 1 and Step 2 fields use plain CF7 shortcodes (no * asterisk) so CF7 does not natively validate them. Our JS validators handle all required field checks instead. This guard only blocks submission if our Step 4 JS check fails (payment upload or stay-connected fields missing). ============================================================ */ var cf7Form = document.querySelector('.wpcf7-form'); if (cf7Form) { cf7Form.addEventListener('submit', function (e) { if (!validateStep4()) { e.preventDefault(); e.stopPropagation(); scrollToFirstError(); } }, true); } document.addEventListener('wpcf7invalid', function (e) { var box = document.getElementById('fx-cf7-error'); if (!box || !e.detail || !e.detail.apiResponse) return; var invalid = (e.detail.apiResponse.invalid_fields || []); if (!invalid.length) return; var msgs = invalid.map(function (f) { return f.message || f.field; }).join(', '); box.textContent = '⚠️ Please fix the following before submitting: ' + msgs; box.style.display = 'block'; box.scrollIntoView({ behavior: 'smooth', block: 'center' }); }, false); document.addEventListener('wpcf7submit', function () { var box = document.getElementById('fx-cf7-error'); if (box) box.style.display = 'none'; }, false); /* ============================================================ INITIALISE ============================================================ */ toggleLevelFields(''); showStep(0); });

    Frequently Asked Questions (FAQs)

    Item #1
    Shopping Cart