Functional Movement Screening Tool

Functional Movement Screening Tool

Assess your movement patterns to identify limitations and asymmetries.

Click the button below to calculate and view your results.

`; default: return ''; } } // --- Tab Navigation & Scoring --- function showTab(tabIndex) { document.querySelectorAll('.tab-btn').forEach((btn, index) => btn.classList.toggle('active', index === tabIndex)); document.querySelectorAll('.tab-content').forEach((content, index) => content.classList.toggle('active', index === tabIndex)); state.currentTabIndex = tabIndex; prevBtn.disabled = state.currentTabIndex === 0; nextBtn.disabled = state.currentTabIndex === screens.length - 1; } function handleScoreChange(e) { state.scores[e.target.name] = parseInt(e.target.value); } function calculateAndShowResults() { let totalScore = 0; const lowScores = []; screens.slice(1, -1).forEach(screen => { const score = state.scores[screen.id]; if (typeof score === 'number') { totalScore += score; if (score <= 1) { lowScores.push(screen.title); } } }); let interpretation = ''; if (totalScore <= 14) { interpretation = 'Your score is 14 or below, which may indicate an increased risk for injury. Focus on the areas with low scores.'; } else { interpretation = 'Your score suggests a good foundation of movement. Continue to work on any areas where you scored a 2.'; } if (lowScores.some(s => s.includes('0'))) { interpretation += ' Pain was noted during the screen. It is highly recommended to consult a healthcare professional.'; } const resultsContent = document.getElementById('results-content'); resultsContent.innerHTML = `

Total Score: ${totalScore} / 21

${interpretation}

${lowScores.length > 0 ? `

Areas for Focus:

${lowScores.join(', ')}

` : ''}
`; resultsContent.style.display = 'block'; document.getElementById('download-pdf-btn').addEventListener('click', generatePDF); } // --- PDF Generation --- async function generatePDF() { const { jsPDF } = window.jspdf; const downloadBtn = document.getElementById('download-pdf-btn'); const originalButtonText = downloadBtn.textContent; downloadBtn.textContent = 'Generating...'; downloadBtn.disabled = true; const pdfWrapper = document.createElement('div'); pdfWrapper.style.position = 'absolute'; pdfWrapper.style.left = '-9999px'; pdfWrapper.style.top = '0'; pdfWrapper.style.width = '800px'; pdfWrapper.style.backgroundColor = 'white'; pdfWrapper.className = 'p-8'; let reportHtml = `

Functional Movement Screen Report

${new Date().toLocaleDateString()}

${document.getElementById('results-content').innerHTML}

Detailed Scores

`; screens.slice(1, -1).forEach(screen => { const score = state.scores[screen.id] ?? 'N/A'; const notes = document.querySelector(`[data-id="${screen.id}"] textarea`).value || ''; reportHtml += ``; }); reportHtml += `
TestScoreNotes
${screen.title}${score}${notes}
`; pdfWrapper.innerHTML = reportHtml; pdfWrapper.querySelector('#download-pdf-btn').remove(); document.body.appendChild(pdfWrapper); try { const canvas = await html2canvas(pdfWrapper, { scale: 2, useCORS: true, logging: false }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'portrait', unit: 'px', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgWidth = canvas.width; const imgHeight = canvas.height; const ratio = imgWidth / imgHeight; let finalImgWidth = pdfWidth; let finalImgHeight = pdfWidth / ratio; if (finalImgHeight > pdfHeight) { finalImgHeight = pdfHeight; finalImgWidth = pdfHeight * ratio; } pdf.addImage(imgData, 'PNG', 0, 0, finalImgWidth, finalImgHeight); pdf.save('FMS-Report.pdf'); } catch (error) { console.error("PDF Generation Error:", error); } finally { document.body.removeChild(pdfWrapper); downloadBtn.textContent = originalButtonText; downloadBtn.disabled = false; } } // --- Event Listeners --- prevBtn.addEventListener('click', () => { if (state.currentTabIndex > 0) showTab(state.currentTabIndex - 1); }); nextBtn.addEventListener('click', () => { if (state.currentTabIndex < screens.length - 1) showTab(state.currentTabIndex + 1); }); // --- Initial Call --- initializeUI(); });
Scroll to Top