@jspsych/plugin-survey-multi-choice 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.browser.js +71 -79
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.min.js +16 -2
- package/dist/index.browser.min.js.map +1 -1
- package/dist/index.cjs +70 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -18
- package/dist/index.js +70 -78
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.spec.ts +32 -1
- package/src/index.ts +40 -71
package/src/index.ts
CHANGED
|
@@ -80,20 +80,7 @@ const info = <const>{
|
|
|
80
80
|
data: {
|
|
81
81
|
/** 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. */
|
|
82
82
|
response: {
|
|
83
|
-
type: ParameterType.
|
|
84
|
-
nested: {
|
|
85
|
-
identifier: {
|
|
86
|
-
type: ParameterType.STRING,
|
|
87
|
-
},
|
|
88
|
-
response: {
|
|
89
|
-
type:
|
|
90
|
-
ParameterType.STRING |
|
|
91
|
-
ParameterType.INT |
|
|
92
|
-
ParameterType.FLOAT |
|
|
93
|
-
ParameterType.BOOL |
|
|
94
|
-
ParameterType.OBJECT,
|
|
95
|
-
},
|
|
96
|
-
},
|
|
83
|
+
type: ParameterType.OBJECT,
|
|
97
84
|
},
|
|
98
85
|
/** 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. */
|
|
99
86
|
rt: {
|
|
@@ -109,6 +96,8 @@ const info = <const>{
|
|
|
109
96
|
|
|
110
97
|
type Info = typeof info;
|
|
111
98
|
|
|
99
|
+
const plugin_id_name = "jspsych-survey-multi-choice";
|
|
100
|
+
|
|
112
101
|
/**
|
|
113
102
|
* **survey-multi-choice**
|
|
114
103
|
*
|
|
@@ -120,38 +109,37 @@ type Info = typeof info;
|
|
|
120
109
|
class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|
121
110
|
static info = info;
|
|
122
111
|
|
|
123
|
-
constructor(private jsPsych: JsPsych) {}
|
|
112
|
+
constructor(private jsPsych: JsPsych) { }
|
|
124
113
|
|
|
125
114
|
trial(display_element: HTMLElement, trial: TrialType<Info>) {
|
|
126
|
-
|
|
115
|
+
|
|
116
|
+
const trial_form_id = `${plugin_id_name}_form`;
|
|
127
117
|
|
|
128
118
|
var html = "";
|
|
129
119
|
|
|
130
120
|
// inject CSS for trial
|
|
131
|
-
html +=
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
121
|
+
html += `
|
|
122
|
+
<style id="${plugin_id_name}-css">
|
|
123
|
+
.${plugin_id_name}-question { margin-top: 2em; margin-bottom: 2em; text-align: left; }
|
|
124
|
+
.${plugin_id_name}-text span.required {color: darkred;}
|
|
125
|
+
.${plugin_id_name}-horizontal .${plugin_id_name}-text { text-align: center;}
|
|
126
|
+
.${plugin_id_name}-option { line-height: 2; }
|
|
127
|
+
.${plugin_id_name}-horizontal .${plugin_id_name}-option { display: inline-block; margin-left: 1em; margin-right: 1em; vertical-align: top;}
|
|
128
|
+
label.${plugin_id_name}-text input[type='radio'] {margin-right: 1em;}
|
|
129
|
+
</style>`;
|
|
140
130
|
|
|
141
131
|
// show preamble text
|
|
142
132
|
if (trial.preamble !== null) {
|
|
143
|
-
html +=
|
|
144
|
-
'<div id="jspsych-survey-multi-choice-preamble" class="jspsych-survey-multi-choice-preamble">' +
|
|
145
|
-
trial.preamble +
|
|
146
|
-
"</div>";
|
|
133
|
+
html += `<div id="${plugin_id_name}-preamble" class="${plugin_id_name}-preamble">${trial.preamble}</div>`;
|
|
147
134
|
}
|
|
148
135
|
|
|
149
136
|
// form element
|
|
150
137
|
if (trial.autocomplete) {
|
|
151
|
-
html +=
|
|
138
|
+
html += `<form id="${trial_form_id}">`;
|
|
152
139
|
} else {
|
|
153
|
-
html +=
|
|
140
|
+
html += `<form id="${trial_form_id}" autocomplete="off">`;
|
|
154
141
|
}
|
|
142
|
+
|
|
155
143
|
// generate question order. this is randomized here as opposed to randomizing the order of trial.questions
|
|
156
144
|
// so that the data are always associated with the same question regardless of order
|
|
157
145
|
var question_order = [];
|
|
@@ -169,22 +157,15 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|
|
169
157
|
var question_id = question_order[i];
|
|
170
158
|
|
|
171
159
|
// create question container
|
|
172
|
-
var question_classes = [
|
|
160
|
+
var question_classes = [`${plugin_id_name}-question`];
|
|
173
161
|
if (question.horizontal) {
|
|
174
|
-
question_classes.push(
|
|
162
|
+
question_classes.push(`${plugin_id_name}-horizontal`);
|
|
175
163
|
}
|
|
176
164
|
|
|
177
|
-
html +=
|
|
178
|
-
'<div id="jspsych-survey-multi-choice-' +
|
|
179
|
-
question_id +
|
|
180
|
-
'" class="' +
|
|
181
|
-
question_classes.join(" ") +
|
|
182
|
-
'" data-name="' +
|
|
183
|
-
question.name +
|
|
184
|
-
'">';
|
|
165
|
+
html += `<div id="${plugin_id_name}-${question_id}" class="${question_classes.join(" ")}" data-name="${question.name}">`;
|
|
185
166
|
|
|
186
167
|
// add question text
|
|
187
|
-
html +=
|
|
168
|
+
html += `<p class="${plugin_id_name}-text survey-multi-choice">${question.prompt}`;
|
|
188
169
|
if (question.required) {
|
|
189
170
|
html += "<span class='required'>*</span>";
|
|
190
171
|
}
|
|
@@ -193,47 +174,35 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|
|
193
174
|
// create option radio buttons
|
|
194
175
|
for (var j = 0; j < question.options.length; j++) {
|
|
195
176
|
// add label and question text
|
|
196
|
-
var option_id_name =
|
|
197
|
-
var input_name =
|
|
198
|
-
var input_id =
|
|
177
|
+
var option_id_name = `${plugin_id_name}-option-${question_id}-${j}`;
|
|
178
|
+
var input_name = `${plugin_id_name}-response-${question_id}`;
|
|
179
|
+
var input_id = `${plugin_id_name}-response-${question_id}-${j}`;
|
|
199
180
|
|
|
200
181
|
var required_attr = question.required ? "required" : "";
|
|
201
182
|
|
|
202
183
|
// add radio button container
|
|
203
|
-
html +=
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
'" value="' +
|
|
211
|
-
question.options[j] +
|
|
212
|
-
'" ' +
|
|
213
|
-
required_attr +
|
|
214
|
-
"></input>";
|
|
215
|
-
html += question.options[j] + "</label>";
|
|
216
|
-
html += "</div>";
|
|
184
|
+
html += `
|
|
185
|
+
<div id="${option_id_name}" class="${plugin_id_name}-option">
|
|
186
|
+
<label class="${plugin_id_name}-text" for="${input_id}">
|
|
187
|
+
<input type="radio" name="${input_name}" id="${input_id}" value="${question.options[j]}" ${required_attr} />
|
|
188
|
+
${question.options[j]}
|
|
189
|
+
</label>
|
|
190
|
+
</div>`;
|
|
217
191
|
}
|
|
218
192
|
|
|
219
193
|
html += "</div>";
|
|
220
194
|
}
|
|
221
195
|
|
|
222
196
|
// add submit button
|
|
223
|
-
html +=
|
|
224
|
-
'<input type="submit" id="' +
|
|
225
|
-
plugin_id_name +
|
|
226
|
-
'-next" class="' +
|
|
227
|
-
plugin_id_name +
|
|
228
|
-
' jspsych-btn"' +
|
|
229
|
-
(trial.button_label ? ' value="' + trial.button_label + '"' : "") +
|
|
230
|
-
"></input>";
|
|
197
|
+
html += `<input type="submit" id="${plugin_id_name}-next" class="${plugin_id_name} jspsych-btn"${trial.button_label ? ' value="' + trial.button_label + '"' : ""} />`;
|
|
231
198
|
html += "</form>";
|
|
232
199
|
|
|
233
200
|
// render
|
|
234
201
|
display_element.innerHTML = html;
|
|
235
202
|
|
|
236
|
-
|
|
203
|
+
const trial_form = display_element.querySelector<HTMLFormElement>(`#${trial_form_id}`);
|
|
204
|
+
|
|
205
|
+
trial_form.addEventListener("submit", (event) => {
|
|
237
206
|
event.preventDefault();
|
|
238
207
|
// measure response time
|
|
239
208
|
var endTime = performance.now();
|
|
@@ -242,7 +211,7 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|
|
242
211
|
// create object to hold responses
|
|
243
212
|
var question_data = {};
|
|
244
213
|
for (var i = 0; i < trial.questions.length; i++) {
|
|
245
|
-
var match = display_element.querySelector(
|
|
214
|
+
var match = display_element.querySelector(`#${plugin_id_name}-${i}`);
|
|
246
215
|
var id = "Q" + i;
|
|
247
216
|
var val: String;
|
|
248
217
|
if (match.querySelector("input[type=radio]:checked") !== null) {
|
|
@@ -330,7 +299,7 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|
|
330
299
|
for (let i = 0; i < answers.length; i++) {
|
|
331
300
|
this.jsPsych.pluginAPI.clickTarget(
|
|
332
301
|
display_element.querySelector(
|
|
333
|
-
|
|
302
|
+
`#${plugin_id_name}-response-${i}-${trial.questions[i].options.indexOf(
|
|
334
303
|
answers[i][1]
|
|
335
304
|
)}`
|
|
336
305
|
),
|
|
@@ -339,7 +308,7 @@ class SurveyMultiChoicePlugin implements JsPsychPlugin<Info> {
|
|
|
339
308
|
}
|
|
340
309
|
|
|
341
310
|
this.jsPsych.pluginAPI.clickTarget(
|
|
342
|
-
display_element.querySelector(
|
|
311
|
+
display_element.querySelector(`#${plugin_id_name}-next`),
|
|
343
312
|
data.rt
|
|
344
313
|
);
|
|
345
314
|
}
|