conditional follow up questions when the main question "YES" is selected.
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.
var jsPsych = initJsPsych();
var timeline = [];
var 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?',
// '3) Do you ever hear your own thoughts repeated or echoed?',
// '4) Do you ever see shapes, lights, or colors even though there is nothing really there?',
// '5) Do you ever experience unusual burning sensations or other strange feelings in or on your body?',
// '6) Do you ever hear noises or sounds when there is nothing about to explain them?',
// '7) Do you ever hear your own thoughts spoken aloud in your head, so that someone near might be able to hear them?',
// '8) Do you ever detect smells which don’t seem to come from your surroundings?',
// '9) Do you ever have the sensation that your body, or a part of it, is changing or has changed shape?',
// '10) Do you ever have the sensation that your limbs might not be your own or might not be properly connected to your body?',
// '11) Do you ever hear voices commenting on what you are thinking or doing?',
// '12) Do you ever feel that someone is touching you, but when you look nobody is there?',
// '13) Do you ever hear voices saying words or sentences when there is no-one around that might account for it?',
// '14) Do you ever experience unexplained tastes in your mouth?',
// '15) Do you ever find that sensations happen all at once and flood you with information?',
// '16) Do you ever find that sounds are distorted in strange or unusual ways?',
// '17) Do you ever have difficulty distinguishing one sensation from another?',
// '18) Do you ever smell everyday odors and think that they are unusually strong?',
// '19) Do you ever find the appearance of things or people seems to change in a puzzling way, e.g., distorted shapes or sizes or color?',
// '20) Do you ever find that your skin is more sensitive to touch, heat, or cold than usual?',
// '21) Do you ever think that food or drink tastes much stronger than it normally would?',
// '22) Do you ever look in the mirror and think that your face seems different from usual?',
// '23) Do you ever have days where lights or colors seem brighter or more intense than usual?',
// '24) Do you ever have the feeling of being uplifted, as if driving or rolling over a road while sitting quietly?',
// '25) Do you ever find that common smells sometimes seem unusually different?',
// '26) Do you ever think that everyday things look abnormal to you?',
// '27) Do you ever find that your experience of time changes dramatically?',
// '28) Have you ever heard two or more unexplained voices talking with each other?',
// '29) Do you ever notice smells or odors that people next to you seem unaware of?',
// '30) Do you ever notice that food or drink seems to have an unusual taste?',
// '31) Do you ever see things that other people cannot?',
// '32) Do you ever hear sounds or music that people near you don’t hear?'
];
// try
function createFollowUpLikert(questionName) {
return {
type: jsPsychSurveyLikert,
questions: [
{ prompt: "Not at all distressing to Very distressing", name: questionName + 'Distressing', labels: ["1", "2", "3", "4", "5"], required: true },
{ prompt: "Not at all distracting to Completely intrusive", name: questionName + 'Distracting', labels: ["1", "2", "3", "4", "5"], required: true },
{ prompt: "Happens hardly at all to Happens all the time", name: questionName + 'Frequency', labels: ["1", "2", "3", "4", "5"], required: true }
]
};
}
function createMainQuestionTrial(questionText, index) {
var questionName = 'Q' + (index + 1);
return {
type: jsPsychSurveyMultiChoice,
questions: [{ prompt: questionText, options: ['NO', 'YES'], required: true, name: questionName }],
on_finish: function(data) {
if(data.response[questionName] === 'YES') {
// If the response is YES, add the follow-up Likert scale questions to the timeline
jsPsych.addNodeToEndOfTimeline(createFollowUpLikert(questionName));
}
}
};
}
// Adding each main question trial to the timeline
caps_qn.forEach(function(questionText, index) {
timeline.push(createMainQuestionTrial(questionText, index));
});
// Start the experiment
jsPsych.run(timeline);
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;
}
Thank you very much. really appreciate it! just wondering how do we decide when to use multi-choice, when to use likert then?
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.