conditional follow up questions when the main question "YES" is selected. #3305
Replies: 3 comments
-
Each trial is bound to be displayed on a separate page, and you are adding the questions and follow-up questions by inserting multiple trials. The correct way would be to display the questions in one multi-choice trial and use on_load to control the addition of follow-up questions. The solution is given below. You might want to take a closer look at the comments to better understand it and for further customization. The javascript code: let jsPsych = initJsPsych();
let timeline = [];
let caps_qn = [
'1) Do you ever notice that sounds are much louder than they normally would be?',
'2) Do you ever sense the presence of another being, despite being unable to see any evidence?',
];
// Add the follow up using multi-choice instead of likert
// After all, the latter can be regarded as a special multi-choice question.
//
// The prefix indicates the name of the question it follows up.
//
// Note though, we are prefixing the name with "follow-up". We are using this name to identify the follow-up querstions
// later.
//
// We are also making the choices display horizontally so that it resembles the real likert survey more.
function create_follow_up_question(prefix) {
let options = [1, 2, 3, 4, 5];
let create_name = (name) => `follow-up-${prefix}-${name}`;
return [
{ prompt: "Not at all distressing to Very distressing", name: create_name('Distressing'), options, horizontal: true },
{ prompt: "Not at all distracting to Completely intrusive", name: create_name('Distracting'), options, horizontal: true },
{ prompt: "Happens hardly at all to Happens all the time", name: create_name('Frequency'), options, horizontal: true }
]
}
let trial = {
type: jsPsychSurveyMultiChoice,
questions: caps_qn.map(function (value, index) {
return [
{
prompt: value,
required: true,
name: `Q${index}`,
options: ['yes', 'no'],
},
create_follow_up_question(`Q${index}`),
];
// flat the array as it looks like this prior to flattening:
//
// [
// [{Q0}, [{follow-up-Q0-Distressing, follow-up-Q0-Distracting}]],
// [{Q1}, [{follow-up-Q1-Distressing, follow-up-Q1-Distracting}]],
// ]
//
// Which is why we have to apply a depth=2 flattening
}).flat(2),
// custom css_classes
// go check out the css code now before proceeding
css_classes: ['survey'],
on_load: function () {
// selects the wrapper div of questions whose name begins with Q, i.e., the non-follow-up questions
for (let elem of document.querySelectorAll('.jspsych-survey-multi-choice-question[data-name^="Q"]')) {
// the radio elements are the child nodes of the wrapper div
let radios = elem.querySelectorAll('input');
for (let radio of radios) {
// listens to click event on the individual radio elements
// if the radio element's value is "yes", show the follow up questions; otherwise, hide them
radio.addEventListener('click', function (event) {
let show_follow_up = event.target.value === 'yes';
// The name is stored in the data-name property of the wrapper div
let name = elem.dataset.name;
// We will be using next-sibling combinator to select the wrapper divs of the follow-up questions
// This is a base of the selector
let selector = `.jspsych-survey-multi-choice-question[data-name^="${name}"]`;
for (let i = 0; i < 3; i++) {
// Move the selector one element further
selector += ' + .jspsych-survey-multi-choice-question';
let follow_up = document.querySelector(selector);
follow_up.style.display = show_follow_up ? 'block' : 'none';
// Do not forget to set the follow-up question as required
follow_up.querySelectorAll('input').forEach(function (elem) {
elem.required = show_follow_up;
})
}
});
}
}
},
}
jsPsych.run([trial]); The CSS code: /* The .survey is defined in the javascript code by `css_classes` */
.survey .jspsych-survey-multi-choice-text {
text-align: left !important;
}
/*
* Remember back when we created the follow-up questions, where we prefixed
* each name with a follow-up? We are now selecting these follow-questions and
* hiding them at the beginning stage.
*/
.survey .jspsych-survey-multi-choice-question[data-name^="follow-up"] {
display: none;
} |
Beta Was this translation helpful? Give feedback.
-
Thank you very much. really appreciate it! just wondering how do we decide when to use multi-choice, when to use likert then? |
Beta Was this translation helpful? Give feedback.
-
I choose to use multi-choice here because, with the addition of the follow-up question, the trial does not consist only of likert items. A yes-or-no question would be troublesome should we try to implement it in a likert trial. If you never need to make much modification to the plugin and require only likert items, use likert. |
Beta Was this translation helpful? Give feedback.
-
I have been trying to set up a questionnaire full of questions working like this:
for each question, the follow up question is displayed when yes is selected.
But right now, the code I have only works: each main question is on a seperate page, and only after answering all the questions, the follow up questions is showed. (i.e. Question 1, Question 2, follow up question for Q1; follow up question for Q2). just wondering if anyone have a idea how can I modify it to make at least the follow up question is on the same page with its question and ideally, all questions are on the same page? ) Thanks in advance.
Beta Was this translation helpful? Give feedback.
All reactions