website

source code for the ttmaths.uk website
Log | Files | Refs | README

commit 57be49f4c638dfe9800cb9b5a5c171590eed9741
parent 9d58e468118b7e1d11ac364b929fc5a1384f7018
Author: hrryt <harry@mayesfield.uk>
Date:   Fri, 31 Jul 2026 23:51:26 +0100

Implement variable question parameters

Diffstat:
Msrc/components/MultipleSelection.jsx | 13+++++++------
Msrc/components/QuestionWindow.jsx | 50+++++++++++++++++++++++++++-----------------------
2 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/src/components/MultipleSelection.jsx b/src/components/MultipleSelection.jsx @@ -1,11 +1,12 @@ import * as React from 'react'; -export default function MultipleSelection({ id, legend, values, labels = values, defaults = values.map(() => true) }) { - const [checked, setChecked] = React.useState(defaults); +export default function MultipleSelection({ parameter, setParameter, id, legend, values, labels = values }) { + checked = values.map(value => parameter.includes(value)); - function updateChecked(newValue, index) { - const newChecked = checked.map((value, i) => i === index ? newValue : value); - setChecked(newChecked.some(Boolean) ? newChecked : checked.map((value) => !value)); + function updateParameter(e, index) { + const newChecked = checked.map((value, i) => i === index ? e.target.checked : value); + const validChecked = newChecked.some(Boolean) ? newChecked : checked.map((value) => !value); + setParameter(values.filter((_, i) => validChecked[i])); } return ( @@ -15,7 +16,7 @@ export default function MultipleSelection({ id, legend, values, labels = values, const name = `${id}:${value}`; return ( <div key={value} className="field-row"> - <input type="checkbox" id={name} name={name} checked={checked[i]} onChange={e => updateChecked(e.target.checked, i)} /> + <input type="checkbox" id={name} name={name} checked={checked[i]} onChange={e => updateParameter(e, i)} /> <label htmlFor={name}>{labels[i]}</label> </div> ); diff --git a/src/components/QuestionWindow.jsx b/src/components/QuestionWindow.jsx @@ -24,32 +24,27 @@ function chooseQuestionComponent(type) { } } -function getFormValue(id, formData) { - // TODO: Implement - return ["a=1"]; -} - -function resolveParameters(question, formData) { +function resolveParameters(question, variableParameters) { const parameters = question.lockedParameters || { }; const controlledParameters = question.controlledParameters || { }; Object.keys(controlledParameters).forEach((key) => { - parameters[key] = getFormValue(controlledParameters[key], formData); + parameters[key] = variableParameters[controlledParameters[key]]; }) return parameters; } -function renderQuestion(seed, showAnswer, formData) { +function renderQuestion(seed, showAnswer, variableParameters) { return (question, i) => { const QuestionComponent = chooseQuestionComponent(question.type); - const parameters = resolveParameters(question, formData); + const parameters = resolveParameters(question, variableParameters); return <QuestionComponent key={i} seed={seed+i} showAnswer={showAnswer} parameters={parameters} />; }; } -function getQuestionList(id, questions, showAnswers, seed, formData) { +function getQuestionList(id, questions, showAnswers, seed, variableParameters) { return ( <QuestionList key={id}> - {questions.map(renderQuestion(seed, showAnswers, formData))} + {questions.map(renderQuestion(seed, showAnswers, variableParameters))} </QuestionList> ); } @@ -59,9 +54,23 @@ function shuffleArray(arr, n, seed) { } export default function QuestionWindow({ data }) { - const [showAnswers, setShowAnswers] = React.useState(false); - const [seed , setSeed ] = React.useState(Math.random()); - const [formData , setFormData ] = React.useState({ }); + + defaultParameters = Object.fromEntries( + data.inputs.map(input => [input.id, input.default ?? input.values]) + ); + + const [showAnswers , setShowAnswers ] = React.useState(false); + const [seed , setSeed ] = React.useState(Math.random()); + const [variableParameters , setVariableParameters ] = React.useState(defaultParameters); + + function setParameter(id) { + return (value) => { + setVariableParameters({ + ...variableParameters, + [id]: value + }); + } + } function revealAnswers() { setShowAnswers(!showAnswers); } function triggerRefresh() { setSeed(getRandomNumber(seed)); } @@ -70,7 +79,7 @@ export default function QuestionWindow({ data }) { const questions = data.questionLists.map(questionList => { const { id: id, n: n, questions: unique_questions } = questionList; const questions = shuffleArray(unique_questions, n, current_seed); - const randomQuestionList = getQuestionList(id, questions, showAnswers, current_seed, formData); + const randomQuestionList = getQuestionList(id, questions, showAnswers, current_seed, variableParameters); current_seed += n; return randomQuestionList; }); @@ -78,19 +87,14 @@ export default function QuestionWindow({ data }) { const fields = data.inputs.map(input => { const { type: type, ...props } = input; const InputComponent = chooseInputComponent(type); - return <InputComponent {...props} />; + return <InputComponent parameter={variableParameters[input.id]} setParameter={setParameter(input.id)} {...props} />; }); - function updateFormData(e) { - const newFormData = new FormData(e.currentTarget); - setFormData(Object.fromEntries(newFormData.entries())); - } + console.log(variableParameters); return ( <Window title="Questions"> - <form onChange={updateFormData}> - {fields} - </form> + {fields} <fieldset> <legend>Options</legend> <button onClick={revealAnswers}>