mirror of
https://github.com/jspsych/jsPsych.git
synced 2025-05-10 11:10:54 +00:00
Merge pull request #3444 from crava2199/plugin-survey-multi-choice-formid-fix
added form id in querySelector to plugin-survey-multi-choice
This commit is contained in:
commit
4303c91b28
5
.changeset/rare-years-draw.md
Normal file
5
.changeset/rare-years-draw.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@jspsych/plugin-survey-multi-choice": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
The plugin will now work in cases where there are multiple forms on the page.
|
@ -1,5 +1,6 @@
|
|||||||
import { clickTarget, simulateTimeline, startTimeline } from "@jspsych/test-utils";
|
import { clickTarget, simulateTimeline, startTimeline } from "@jspsych/test-utils";
|
||||||
|
|
||||||
|
import { initJsPsych } from "jspsych";
|
||||||
import surveyMultiChoice from ".";
|
import surveyMultiChoice from ".";
|
||||||
|
|
||||||
jest.useFakeTimers();
|
jest.useFakeTimers();
|
||||||
@ -10,6 +11,36 @@ const getInputElement = (choiceId: number, value: string) =>
|
|||||||
) as HTMLInputElement;
|
) as HTMLInputElement;
|
||||||
|
|
||||||
describe("survey-multi-choice plugin", () => {
|
describe("survey-multi-choice plugin", () => {
|
||||||
|
test("properly ends when has sibling form", async () => {
|
||||||
|
|
||||||
|
const container = document.createElement('div')
|
||||||
|
const outerForm = document.createElement('form')
|
||||||
|
outerForm.id = 'outer_form'
|
||||||
|
container.appendChild(outerForm)
|
||||||
|
const innerDiv = document.createElement('div')
|
||||||
|
innerDiv.id = 'target_id';
|
||||||
|
container.appendChild(innerDiv);
|
||||||
|
document.body.appendChild(container)
|
||||||
|
const jsPsychInst = initJsPsych({ display_element: innerDiv })
|
||||||
|
const options = ["a", "b", "c"];
|
||||||
|
|
||||||
|
const { getData, expectFinished } = await startTimeline([
|
||||||
|
{
|
||||||
|
type: surveyMultiChoice,
|
||||||
|
questions: [
|
||||||
|
{ prompt: "Q0", options },
|
||||||
|
{ prompt: "Q1", options },
|
||||||
|
]
|
||||||
|
},
|
||||||
|
], jsPsychInst);
|
||||||
|
|
||||||
|
getInputElement(0, "a").checked = true;
|
||||||
|
await clickTarget(document.querySelector("#jspsych-survey-multi-choice-next"));
|
||||||
|
await expectFinished();
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
test("data are logged with the right question when randomize order is true", async () => {
|
test("data are logged with the right question when randomize order is true", async () => {
|
||||||
var scale = ["a", "b", "c", "d", "e"];
|
var scale = ["a", "b", "c", "d", "e"];
|
||||||
const { getData, expectFinished } = await startTimeline([
|
const { getData, expectFinished } = await startTimeline([
|
||||||
@ -45,7 +76,7 @@ describe("survey-multi-choice plugin", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("survey-likert plugin simulation", () => {
|
describe("survey-multi-choice plugin simulation", () => {
|
||||||
test("data-only mode works", async () => {
|
test("data-only mode works", async () => {
|
||||||
const scale = ["a", "b", "c", "d", "e"];
|
const scale = ["a", "b", "c", "d", "e"];
|
||||||
const { getData, expectFinished } = await simulateTimeline([
|
const { getData, expectFinished } = await simulateTimeline([
|
||||||
|
@ -96,6 +96,8 @@ const info = <const>{
|
|||||||
|
|
||||||
type Info = typeof info;
|
type Info = typeof info;
|
||||||
|
|
||||||
|
const plugin_id_name = "jspsych-survey-multi-choice";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **survey-multi-choice**
|
* **survey-multi-choice**
|
||||||
*
|
*
|
||||||
@ -110,35 +112,34 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|||||||
constructor(private jsPsych: JsPsych) { }
|
constructor(private jsPsych: JsPsych) { }
|
||||||
|
|
||||||
trial(display_element: HTMLElement, trial: TrialType<Info>) {
|
trial(display_element: HTMLElement, trial: TrialType<Info>) {
|
||||||
var plugin_id_name = "jspsych-survey-multi-choice";
|
|
||||||
|
const trial_form_id = `${plugin_id_name}_form`;
|
||||||
|
|
||||||
var html = "";
|
var html = "";
|
||||||
|
|
||||||
// inject CSS for trial
|
// inject CSS for trial
|
||||||
html += '<style id="jspsych-survey-multi-choice-css">';
|
html += `
|
||||||
html +=
|
<style id="${plugin_id_name}-css">
|
||||||
".jspsych-survey-multi-choice-question { margin-top: 2em; margin-bottom: 2em; text-align: left; }" +
|
.${plugin_id_name}-question { margin-top: 2em; margin-bottom: 2em; text-align: left; }
|
||||||
".jspsych-survey-multi-choice-text span.required {color: darkred;}" +
|
.${plugin_id_name}-text span.required {color: darkred;}
|
||||||
".jspsych-survey-multi-choice-horizontal .jspsych-survey-multi-choice-text { text-align: center;}" +
|
.${plugin_id_name}-horizontal .${plugin_id_name}-text { text-align: center;}
|
||||||
".jspsych-survey-multi-choice-option { line-height: 2; }" +
|
.${plugin_id_name}-option { line-height: 2; }
|
||||||
".jspsych-survey-multi-choice-horizontal .jspsych-survey-multi-choice-option { display: inline-block; margin-left: 1em; margin-right: 1em; vertical-align: top;}" +
|
.${plugin_id_name}-horizontal .${plugin_id_name}-option { display: inline-block; margin-left: 1em; margin-right: 1em; vertical-align: top;}
|
||||||
"label.jspsych-survey-multi-choice-text input[type='radio'] {margin-right: 1em;}";
|
label.${plugin_id_name}-text input[type='radio'] {margin-right: 1em;}
|
||||||
html += "</style>";
|
</style>`;
|
||||||
|
|
||||||
// show preamble text
|
// show preamble text
|
||||||
if (trial.preamble !== null) {
|
if (trial.preamble !== null) {
|
||||||
html +=
|
html += `<div id="${plugin_id_name}-preamble" class="${plugin_id_name}-preamble">${trial.preamble}</div>`;
|
||||||
'<div id="jspsych-survey-multi-choice-preamble" class="jspsych-survey-multi-choice-preamble">' +
|
|
||||||
trial.preamble +
|
|
||||||
"</div>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// form element
|
// form element
|
||||||
if (trial.autocomplete) {
|
if (trial.autocomplete) {
|
||||||
html += '<form id="jspsych-survey-multi-choice-form">';
|
html += `<form id="${trial_form_id}">`;
|
||||||
} else {
|
} else {
|
||||||
html += '<form id="jspsych-survey-multi-choice-form" autocomplete="off">';
|
html += `<form id="${trial_form_id}" autocomplete="off">`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate question order. this is randomized here as opposed to randomizing the order of trial.questions
|
// generate question order. this is randomized here as opposed to randomizing the order of trial.questions
|
||||||
// so that the data are always associated with the same question regardless of order
|
// so that the data are always associated with the same question regardless of order
|
||||||
var question_order = [];
|
var question_order = [];
|
||||||
@ -156,22 +157,15 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|||||||
var question_id = question_order[i];
|
var question_id = question_order[i];
|
||||||
|
|
||||||
// create question container
|
// create question container
|
||||||
var question_classes = ["jspsych-survey-multi-choice-question"];
|
var question_classes = [`${plugin_id_name}-question`];
|
||||||
if (question.horizontal) {
|
if (question.horizontal) {
|
||||||
question_classes.push("jspsych-survey-multi-choice-horizontal");
|
question_classes.push(`${plugin_id_name}-horizontal`);
|
||||||
}
|
}
|
||||||
|
|
||||||
html +=
|
html += `<div id="${plugin_id_name}-${question_id}" class="${question_classes.join(" ")}" data-name="${question.name}">`;
|
||||||
'<div id="jspsych-survey-multi-choice-' +
|
|
||||||
question_id +
|
|
||||||
'" class="' +
|
|
||||||
question_classes.join(" ") +
|
|
||||||
'" data-name="' +
|
|
||||||
question.name +
|
|
||||||
'">';
|
|
||||||
|
|
||||||
// add question text
|
// add question text
|
||||||
html += '<p class="jspsych-survey-multi-choice-text survey-multi-choice">' + question.prompt;
|
html += `<p class="${plugin_id_name}-text survey-multi-choice">${question.prompt}`;
|
||||||
if (question.required) {
|
if (question.required) {
|
||||||
html += "<span class='required'>*</span>";
|
html += "<span class='required'>*</span>";
|
||||||
}
|
}
|
||||||
@ -180,47 +174,35 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|||||||
// create option radio buttons
|
// create option radio buttons
|
||||||
for (var j = 0; j < question.options.length; j++) {
|
for (var j = 0; j < question.options.length; j++) {
|
||||||
// add label and question text
|
// add label and question text
|
||||||
var option_id_name = "jspsych-survey-multi-choice-option-" + question_id + "-" + j;
|
var option_id_name = `${plugin_id_name}-option-${question_id}-${j}`;
|
||||||
var input_name = "jspsych-survey-multi-choice-response-" + question_id;
|
var input_name = `${plugin_id_name}-response-${question_id}`;
|
||||||
var input_id = "jspsych-survey-multi-choice-response-" + question_id + "-" + j;
|
var input_id = `${plugin_id_name}-response-${question_id}-${j}`;
|
||||||
|
|
||||||
var required_attr = question.required ? "required" : "";
|
var required_attr = question.required ? "required" : "";
|
||||||
|
|
||||||
// add radio button container
|
// add radio button container
|
||||||
html += '<div id="' + option_id_name + '" class="jspsych-survey-multi-choice-option">';
|
html += `
|
||||||
html += '<label class="jspsych-survey-multi-choice-text" for="' + input_id + '">';
|
<div id="${option_id_name}" class="${plugin_id_name}-option">
|
||||||
html +=
|
<label class="${plugin_id_name}-text" for="${input_id}">
|
||||||
'<input type="radio" name="' +
|
<input type="radio" name="${input_name}" id="${input_id}" value="${question.options[j]}" ${required_attr} />
|
||||||
input_name +
|
${question.options[j]}
|
||||||
'" id="' +
|
</label>
|
||||||
input_id +
|
</div>`;
|
||||||
'" value="' +
|
|
||||||
question.options[j] +
|
|
||||||
'" ' +
|
|
||||||
required_attr +
|
|
||||||
"></input>";
|
|
||||||
html += question.options[j] + "</label>";
|
|
||||||
html += "</div>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html += "</div>";
|
html += "</div>";
|
||||||
}
|
}
|
||||||
|
|
||||||
// add submit button
|
// add submit button
|
||||||
html +=
|
html += `<input type="submit" id="${plugin_id_name}-next" class="${plugin_id_name} jspsych-btn"${trial.button_label ? ' value="' + trial.button_label + '"' : ""} />`;
|
||||||
'<input type="submit" id="' +
|
|
||||||
plugin_id_name +
|
|
||||||
'-next" class="' +
|
|
||||||
plugin_id_name +
|
|
||||||
' jspsych-btn"' +
|
|
||||||
(trial.button_label ? ' value="' + trial.button_label + '"' : "") +
|
|
||||||
"></input>";
|
|
||||||
html += "</form>";
|
html += "</form>";
|
||||||
|
|
||||||
// render
|
// render
|
||||||
display_element.innerHTML = html;
|
display_element.innerHTML = html;
|
||||||
|
|
||||||
document.querySelector("form").addEventListener("submit", (event) => {
|
const trial_form = display_element.querySelector<HTMLFormElement>(`#${trial_form_id}`);
|
||||||
|
|
||||||
|
trial_form.addEventListener("submit", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
// measure response time
|
// measure response time
|
||||||
var endTime = performance.now();
|
var endTime = performance.now();
|
||||||
@ -229,7 +211,7 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|||||||
// create object to hold responses
|
// create object to hold responses
|
||||||
var question_data = {};
|
var question_data = {};
|
||||||
for (var i = 0; i < trial.questions.length; i++) {
|
for (var i = 0; i < trial.questions.length; i++) {
|
||||||
var match = display_element.querySelector("#jspsych-survey-multi-choice-" + i);
|
var match = display_element.querySelector(`#${plugin_id_name}-${i}`);
|
||||||
var id = "Q" + i;
|
var id = "Q" + i;
|
||||||
var val: String;
|
var val: String;
|
||||||
if (match.querySelector("input[type=radio]:checked") !== null) {
|
if (match.querySelector("input[type=radio]:checked") !== null) {
|
||||||
@ -317,7 +299,7 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|||||||
for (let i = 0; i < answers.length; i++) {
|
for (let i = 0; i < answers.length; i++) {
|
||||||
this.jsPsych.pluginAPI.clickTarget(
|
this.jsPsych.pluginAPI.clickTarget(
|
||||||
display_element.querySelector(
|
display_element.querySelector(
|
||||||
`#jspsych-survey-multi-choice-response-${i}-${trial.questions[i].options.indexOf(
|
`#${plugin_id_name}-response-${i}-${trial.questions[i].options.indexOf(
|
||||||
answers[i][1]
|
answers[i][1]
|
||||||
)}`
|
)}`
|
||||||
),
|
),
|
||||||
@ -326,7 +308,7 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.jsPsych.pluginAPI.clickTarget(
|
this.jsPsych.pluginAPI.clickTarget(
|
||||||
display_element.querySelector("#jspsych-survey-multi-choice-next"),
|
display_element.querySelector(`#${plugin_id_name}-next`),
|
||||||
data.rt
|
data.rt
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user