@jspsych/plugin-survey-text
Version:
a jspsych plugin for free response survey questions
1 lines • 20.1 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from \"jspsych\";\n\nimport { version } from \"../package.json\";\n\nconst info = <const>{\n name: \"survey-text\",\n version: version,\n parameters: {\n /**\n * An array of objects, each object represents a question that appears on the screen. Each object contains a prompt,\n * options, required, and horizontal parameter that will be applied to the question. See examples below for further\n * clarification.`prompt`: Type string, default value is *undefined*. The string is prompt/question that will be\n * associated with a group of options (radio buttons). All questions will get presented on the same page (trial).\n * `options`: Type array, defualt value is *undefined*. An array of strings. The array contains a set of options to\n * display for an individual question.`required`: Type boolean, default value is null. The boolean value indicates\n * if a question is required('true') or not ('false'), using the HTML5 `required` attribute. If this parameter is\n * undefined, the question will be optional. `horizontal`:Type boolean, default value is false. If true, then the\n * question is centered and the options are displayed horizontally. `name`: Name of the question. Used for storing\n * data. If left undefined then default names (`Q0`, `Q1`, `...`) will be used for the questions.\n */\n questions: {\n type: ParameterType.COMPLEX,\n array: true,\n default: undefined,\n nested: {\n /** Question prompt. */\n prompt: {\n type: ParameterType.HTML_STRING,\n default: undefined,\n },\n /** Placeholder text in the response text box. */\n placeholder: {\n type: ParameterType.STRING,\n default: \"\",\n },\n /** The number of rows for the response text box. */\n rows: {\n type: ParameterType.INT,\n default: 1,\n },\n /** The number of columns for the response text box. */\n columns: {\n type: ParameterType.INT,\n default: 40,\n },\n /** Whether or not a response to this question must be given in order to continue. */\n required: {\n type: ParameterType.BOOL,\n default: false,\n },\n /** Name of the question in the trial data. If no name is given, the questions are named Q0, Q1, etc. */\n name: {\n type: ParameterType.STRING,\n default: \"\",\n },\n },\n },\n /**\n * If true, the display order of `questions` is randomly determined at the start of the trial. In the data\n * object, `Q0` will still refer to the first question in the array, regardless of where it was presented\n * visually.\n */\n randomize_question_order: {\n type: ParameterType.BOOL,\n default: false,\n },\n /** HTML formatted string to display at the top of the page above all the questions. */\n preamble: {\n type: ParameterType.HTML_STRING,\n default: null,\n },\n /** Label of the button to submit responses. */\n button_label: {\n type: ParameterType.STRING,\n default: \"Continue\",\n },\n /** Setting this to true will enable browser auto-complete or auto-fill for the form. */\n autocomplete: {\n type: ParameterType.BOOL,\n default: false,\n },\n },\n data: {\n /** An object containing the response for each question. The object will have a separate key (variable) for each question, with the first question in the trial being recorded in `Q0`, the second in `Q1`, and so on. The responses are recorded as integers, representing the position selected on the likert scale for that question. If the `name` parameter is defined for the question, then the response object will use the value of `name` as the key for each question. This will be encoded as a JSON string when data is saved using the `.json()` or `.csv()` functions. */\n response: {\n type: ParameterType.COMPLEX,\n nested: {\n identifier: {\n type: ParameterType.STRING,\n },\n response: {\n type:\n ParameterType.STRING |\n ParameterType.INT |\n ParameterType.FLOAT |\n ParameterType.BOOL |\n ParameterType.OBJECT,\n },\n },\n },\n /** The response time in milliseconds for the participant to make a response. The time is measured from when the questions first appear on the screen until the participant's response(s) are submitted. */\n rt: {\n type: ParameterType.INT,\n },\n /** An array with the order of questions. For example `[2,0,1]` would indicate that the first question was `trial.questions[2]` (the third item in the `questions` parameter), the second question was `trial.questions[0]`, and the final question was `trial.questions[1]`. This will be encoded as a JSON string when data is saved using the `.json()` or `.csv()` functions. */\n question_order: {\n type: ParameterType.INT,\n array: true,\n },\n },\n};\n\ntype Info = typeof info;\n\n/**\n *\n * The survey-text plugin displays a set of questions with free response text fields. The participant types in answers.\n *\n * @author Josh de Leeuw\n * @see {@link https://www.jspsych.org/latest/plugins/survey-text/ survey-text plugin documentation on jspsych.org}\n */\nclass SurveyTextPlugin implements JsPsychPlugin<Info> {\n static info = info;\n\n constructor(private jsPsych: JsPsych) {}\n\n trial(display_element: HTMLElement, trial: TrialType<Info>) {\n for (var i = 0; i < trial.questions.length; i++) {\n if (typeof trial.questions[i].rows == \"undefined\") {\n trial.questions[i].rows = 1;\n }\n }\n for (var i = 0; i < trial.questions.length; i++) {\n if (typeof trial.questions[i].columns == \"undefined\") {\n trial.questions[i].columns = 40;\n }\n }\n for (var i = 0; i < trial.questions.length; i++) {\n if (typeof trial.questions[i].value == \"undefined\") {\n trial.questions[i].value = \"\";\n }\n }\n\n var html = \"\";\n // show preamble text\n if (trial.preamble !== null) {\n html +=\n '<div id=\"jspsych-survey-text-preamble\" class=\"jspsych-survey-text-preamble\">' +\n trial.preamble +\n \"</div>\";\n }\n // start form\n if (trial.autocomplete) {\n html += '<form id=\"jspsych-survey-text-form\">';\n } else {\n html += '<form id=\"jspsych-survey-text-form\" autocomplete=\"off\">';\n }\n // generate question order\n var question_order = [];\n for (var i = 0; i < trial.questions.length; i++) {\n question_order.push(i);\n }\n if (trial.randomize_question_order) {\n question_order = this.jsPsych.randomization.shuffle(question_order);\n }\n\n // add questions\n for (var i = 0; i < trial.questions.length; i++) {\n var question = trial.questions[question_order[i]];\n var question_index = question_order[i];\n html +=\n '<div id=\"jspsych-survey-text-' +\n question_index +\n '\" class=\"jspsych-survey-text-question\" style=\"margin: 2em 0em;\">';\n html += '<p class=\"jspsych-survey-text\">' + question.prompt + \"</p>\";\n var autofocus = i == 0 ? \"autofocus\" : \"\";\n var req = question.required ? \"required\" : \"\";\n if (question.rows == 1) {\n html +=\n '<input type=\"text\" id=\"input-' +\n question_index +\n '\" name=\"#jspsych-survey-text-response-' +\n question_index +\n '\" data-name=\"' +\n question.name +\n '\" size=\"' +\n question.columns +\n '\" ' +\n autofocus +\n \" \" +\n req +\n ' placeholder=\"' +\n question.placeholder +\n '\"></input>';\n } else {\n html +=\n '<textarea id=\"input-' +\n question_index +\n '\" name=\"#jspsych-survey-text-response-' +\n question_index +\n '\" data-name=\"' +\n question.name +\n '\" cols=\"' +\n question.columns +\n '\" rows=\"' +\n question.rows +\n '\" ' +\n autofocus +\n \" \" +\n req +\n ' placeholder=\"' +\n question.placeholder +\n '\"></textarea>';\n }\n html += \"</div>\";\n }\n\n // add submit button\n html +=\n '<input type=\"submit\" id=\"jspsych-survey-text-next\" class=\"jspsych-btn jspsych-survey-text\" value=\"' +\n trial.button_label +\n '\"></input>';\n\n html += \"</form>\";\n display_element.innerHTML = html;\n\n // backup in case autofocus doesn't work\n display_element.querySelector<HTMLInputElement>(\"#input-\" + question_order[0]).focus();\n\n display_element.querySelector(\"#jspsych-survey-text-form\").addEventListener(\"submit\", (e) => {\n e.preventDefault();\n // measure response time\n var endTime = performance.now();\n var response_time = Math.round(endTime - startTime);\n\n // create object to hold responses\n var question_data = {};\n\n for (var index = 0; index < trial.questions.length; index++) {\n var id = \"Q\" + index;\n var q_element = document\n .querySelector(\"#jspsych-survey-text-\" + index)\n .querySelector(\"textarea, input\") as HTMLInputElement;\n var val = q_element.value;\n var name = q_element.attributes[\"data-name\"].value;\n if (name == \"\") {\n name = id;\n }\n var obje = {};\n obje[name] = val;\n Object.assign(question_data, obje);\n }\n // save data\n var trialdata = {\n rt: response_time,\n response: question_data,\n };\n\n // next trial\n this.jsPsych.finishTrial(trialdata);\n });\n\n var startTime = performance.now();\n }\n\n simulate(\n trial: TrialType<Info>,\n simulation_mode,\n simulation_options: any,\n load_callback: () => void\n ) {\n if (simulation_mode == \"data-only\") {\n load_callback();\n this.simulate_data_only(trial, simulation_options);\n }\n if (simulation_mode == \"visual\") {\n this.simulate_visual(trial, simulation_options, load_callback);\n }\n }\n\n private create_simulation_data(trial: TrialType<Info>, simulation_options) {\n const question_data = {};\n let rt = 1000;\n\n for (const q of trial.questions) {\n const name = q.name ? q.name : `Q${trial.questions.indexOf(q)}`;\n const ans_words =\n q.rows == 1\n ? this.jsPsych.randomization.sampleExponential(0.25)\n : this.jsPsych.randomization.randomInt(1, 10) * q.rows;\n question_data[name] = this.jsPsych.randomization.randomWords({\n exactly: ans_words,\n join: \" \",\n });\n rt += this.jsPsych.randomization.sampleExGaussian(2000, 400, 0.004, true);\n }\n\n const default_data = {\n response: question_data,\n rt: rt,\n };\n\n const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);\n\n this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);\n\n return data;\n }\n\n private simulate_data_only(trial: TrialType<Info>, simulation_options) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n this.jsPsych.finishTrial(data);\n }\n\n private simulate_visual(trial: TrialType<Info>, simulation_options, load_callback: () => void) {\n const data = this.create_simulation_data(trial, simulation_options);\n\n const display_element = this.jsPsych.getDisplayElement();\n\n this.trial(display_element, trial);\n load_callback();\n\n const answers = Object.entries(data.response).map((x) => {\n return x[1] as string;\n });\n for (let i = 0; i < answers.length; i++) {\n this.jsPsych.pluginAPI.fillTextInput(\n display_element.querySelector(`#input-${i}`),\n answers[i],\n ((data.rt - 1000) / answers.length) * (i + 1)\n );\n }\n\n this.jsPsych.pluginAPI.clickTarget(\n display_element.querySelector(\"#jspsych-survey-text-next\"),\n data.rt\n );\n }\n}\n\nexport default SurveyTextPlugin;\n"],"names":["version","ParameterType"],"mappings":"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"}