Replies: 2 comments
-
Hi @trig11
|
Beta Was this translation helpful? Give feedback.
0 replies
-
Also, for some reason I can't get the window.scrollTo(0,0) function call to work from Firefox' console anymore (I don't quite get why). The html file: <!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<title>Main Experiment</title>
<script src="https://unpkg.com/[email protected]"></script>
<link href="scroll.css" rel="stylesheet" type="text/css"></link>
<link href="styles/jspsych.css" rel="stylesheet" type="text/css"></link>
<!-- Adapted plugins -->
<script src="tr_plugins/tr-plugin-survey-number.js"> </script>
</head>
<body></body>
<script>
/* initialize jsPsych */
var jsPsych = initJsPsych({
override_safe_mode: true,
on_finish: function() {
jsPsych.data.displayData();
}
});
/* create timeline */
var timeline = [];
var scroll_issue_trial = {
type: jsPsychSurveyNumber,
data: jsPsych.timelineVariable('data'),
on_load: function(){
window.scrollTo(0,0);
},
preamble:
"<div id='outer' class='trial_content' > "+
"<div class='container_header'>"+
"<div class='head_img'> <img width='120' height='120' src='img/blue.png' alt='alt_text' ></div>"+
"<div class='name' >'Otto Normalverbraucher'</div>"+
"<div class='bullets'> <ul>"+
"<li>'some more text'</li>"+
"<li>'some more text'</li>"+
"<li>'even more text'</li>"+
"</ul></div>"+
"</div>"+
"<div class='main_body' > "+
"X-Ray: <br>"+
"<img width='800' height='800' src='img/orange.png' alt='img'> "+
"<div class='recommendation' style='font-size: 24px; border: 5px solid black'>Some boxed text here 123 <br> 456 <br> </div> <br>"+
"<div class='recommendation' style='font-size: 24px; border: 5px solid red'>Some more boxed text here 123456<br> </div>"+
"",
questions: [
{prompt: "<div> Your final decision: <br> Put in some number below </div>",
columns: 8,
min_val: 0,
max_val: 100,
step_size: 1,
required: true,
name: 'input'}
],
button_time: 1000,
};
var scroll_timeline = {
timeline: [scroll_issue_trial],
randomize_order: false,
repetitions: 5
}
timeline.push(scroll_timeline);
/* start the experiment */
jsPsych.run(timeline);
</script>
</html> My modified plugin: var jsPsychSurveyNumber = (function (jspsych) { //NOTE TR: changed the plugin name
'use strict';
const info = {
name: "survey-number", // NOTE TR: changed the plugin name
parameters: {
questions: {
type: jspsych.ParameterType.COMPLEX,
array: true,
pretty_name: "Questions",
default: undefined,
nested: {
/** Question prompt. */
prompt: {
type: jspsych.ParameterType.HTML_STRING,
pretty_name: "Prompt",
default: undefined,
},
/** Placeholder text in the response text box. */
placeholder: {
type: jspsych.ParameterType.STRING,
pretty_name: "Placeholder",
default: "",
},
/** The number of rows for the response text box. */
rows: {
type: jspsych.ParameterType.INT,
pretty_name: "Rows",
default: 1,
},
/** The number of columns for the response text box. */
columns: {
type: jspsych.ParameterType.INT,
pretty_name: "Columns",
default: 40,
},
/** NOTE TR: By how much the input in-/decreases when clicking in-/decrease */
step_size: {
type: jspsych.ParameterType.INT,
pretty_name: "Step Size",
default: 1,
},
/** NOTE TR: What is the minimum input for the field */
min_val: {
type: jspsych.ParameterType.INT,
pretty_name: "Minimum Value Input",
default: 0,
},
/** NOTE TR: What is the maximum input for the field */
max_val: {
type: jspsych.ParameterType.INT,
pretty_name: "Maximum Value Input",
default: 100,
},
/** Whether or not a response to this question must be given in order to continue. */
required: {
type: jspsych.ParameterType.BOOL,
pretty_name: "Required",
default: false,
},
/** Name of the question in the trial data. If no name is given, the questions are named Q0, Q1, etc. */
name: {
type: jspsych.ParameterType.STRING,
pretty_name: "Question Name",
default: "",
},
},
},
/** If true, the order of the questions in the 'questions' array will be randomized. */
randomize_question_order: {
type: jspsych.ParameterType.BOOL,
pretty_name: "Randomize Question Order",
default: false,
},
/** HTML-formatted string to display at top of the page above all of the questions. */
preamble: {
type: jspsych.ParameterType.HTML_STRING,
pretty_name: "Preamble",
default: null,
},
/** Label of the button to submit responses. */
button_label: {
type: jspsych.ParameterType.STRING,
pretty_name: "Button label",
default: "Continue",
},
/** NOTE TR: Time after which a response can be submitted (i.e., button is enabled after this time). */
button_time: {
type: jspsych.ParameterType.INT,
pretty_name: "Button time",
default: 0,
},
/** Setting this to true will enable browser auto-complete or auto-fill for the form. */
autocomplete: {
type: jspsych.ParameterType.BOOL,
pretty_name: "Allow autocomplete",
default: false,
},
},
};
/**
* **survey-text**
*
* jsPsych plugin for free text response survey questions
*
* @author Josh de Leeuw
* @see {@link https://www.jspsych.org/plugins/jspsych-survey-text/ survey-text plugin documentation on jspsych.org}
*/
class SurveyTextPlugin {
constructor(jsPsych) {
this.jsPsych = jsPsych;
}
trial(display_element, trial) {
for (var i = 0; i < trial.questions.length; i++) {
if (typeof trial.questions[i].rows == "undefined") {
trial.questions[i].rows = 1;
}
}
for (var i = 0; i < trial.questions.length; i++) {
if (typeof trial.questions[i].columns == "undefined") {
trial.questions[i].columns = 40;
}
}
for (var i = 0; i < trial.questions.length; i++) {
if (typeof trial.questions[i].value == "undefined") {
trial.questions[i].value = "";
}
}
var html = "";
// show preamble text
if (trial.preamble !== null) {
html +=
'<div id="jspsych-survey-text-preamble" class="input_site">' + //NOTE TR: removed class class="jspsych-survey-text-preamble"
trial.preamble ;//NOTE TR: removed +
//"</div>"; NOTE TR: changed end of div to the end of the button down below
}
// start form
if (trial.autocomplete) {
html += '<form id="jspsych-survey-text-form">';
}
else {
html += '<form id="jspsych-survey-text-form" autocomplete="off">';
}
// generate question order
var question_order = [];
for (var i = 0; i < trial.questions.length; i++) {
question_order.push(i);
}
if (trial.randomize_question_order) {
question_order = this.jsPsych.randomization.shuffle(question_order);
}
// add questions
for (var i = 0; i < trial.questions.length; i++) {
var question = trial.questions[question_order[i]];
var question_index = question_order[i];
html +=
'<div id="jspsych-survey-text-' +
question_index +
'" class="number_question" style="margin: 2em 0em;">'; //NOTE TR: changed style, also removed class class="question_style_2"
html += '<p class="number_question">' + question.prompt + "</p>"; // NOTE TR: changed style class, also removed class="question_style_2"
var autofocus = i == 0 ? "autofocus" : "";
var req = question.required ? "required" : "";
if (question.rows == 1) {
html +=
'<input type="number" step="'+question.step_size+'" min="'+question.min_val+'" max="'+question.max_val+'" id="input-' + //NOTE TR: changed the input type and added step min max
question_index +
'" name="#jspsych-survey-text-response-' +
question_index +
'" data-name="' +
question.name +
'" size="' +
question.columns +
'" ' +
autofocus +
" " +
req +
' placeholder="' +
question.placeholder +
'"></input>';
}
else {
html +=
'<textarea id="input-' +
question_index +
'" name="#jspsych-survey-text-response-' +
question_index +
'" data-name="' +
question.name +
'" cols="' +
question.columns +
'" rows="' +
question.rows +
'" ' +
autofocus +
" " +
req +
' placeholder="' +
question.placeholder +
'"></textarea>';
}
html += "</div>";
}
// add submit button
html +=
'<input class="number_button" type="submit" id="jspsych-survey-text-next" disabled="true" value="' + //NOTE TR: changed class of button --> also removed class="jspsych-btn question_style_btn_2"; initially disabled
trial.button_label +
'"></input>';
html += "</form> </div></div></div>"; //NOTE TR: added </div>
// NOTE TR: enables button after predefined time
setTimeout(function(){ document.getElementById('jspsych-survey-text-next').disabled=false}, trial.button_time); // TR NOTE: makes the next button clickable after specific duration
display_element.innerHTML = html;
// backup in case autofocus doesn't work
display_element.querySelector("#input-" + question_order[0]).focus();
display_element.querySelector("#jspsych-survey-text-form").addEventListener("submit", (e) => {
e.preventDefault();
// measure response time
var endTime = performance.now();
var response_time = Math.round(endTime - startTime);
// create object to hold responses
var question_data = {};
for (var index = 0; index < trial.questions.length; index++) {
var id = "Q" + index;
var q_element = document
.querySelector("#jspsych-survey-text-" + index)
.querySelector("textarea, input");
var val = q_element.value;
var name = q_element.attributes["data-name"].value;
if (name == "") {
name = id;
}
var obje = {};
obje[name] = val;
Object.assign(question_data, obje);
}
// save data
var trialdata = {
rt: response_time,
response: question_data,
};
display_element.innerHTML = "";
// next trial
this.jsPsych.finishTrial(trialdata);
});
var startTime = performance.now();
}
simulate(trial, simulation_mode, simulation_options, load_callback) {
if (simulation_mode == "data-only") {
load_callback();
this.simulate_data_only(trial, simulation_options);
}
if (simulation_mode == "visual") {
this.simulate_visual(trial, simulation_options, load_callback);
}
}
create_simulation_data(trial, simulation_options) {
const question_data = {};
let rt = 1000;
for (const q of trial.questions) {
const name = q.name ? q.name : `Q${trial.questions.indexOf(q)}`;
const ans_words = q.rows == 1
? this.jsPsych.randomization.sampleExponential(0.25)
: this.jsPsych.randomization.randomInt(1, 10) * q.rows;
question_data[name] = this.jsPsych.randomization.randomWords({
exactly: ans_words,
join: " ",
});
rt += this.jsPsych.randomization.sampleExGaussian(2000, 400, 0.004, true);
}
const default_data = {
response: question_data,
rt: rt,
};
const data = this.jsPsych.pluginAPI.mergeSimulationData(default_data, simulation_options);
this.jsPsych.pluginAPI.ensureSimulationDataConsistency(trial, data);
return data;
}
simulate_data_only(trial, simulation_options) {
const data = this.create_simulation_data(trial, simulation_options);
this.jsPsych.finishTrial(data);
}
simulate_visual(trial, simulation_options, load_callback) {
const data = this.create_simulation_data(trial, simulation_options);
const display_element = this.jsPsych.getDisplayElement();
this.trial(display_element, trial);
load_callback();
const answers = Object.entries(data.response).map((x) => {
return x[1];
});
for (let i = 0; i < answers.length; i++) {
this.jsPsych.pluginAPI.fillTextInput(display_element.querySelector(`#input-${i}`), answers[i], ((data.rt - 1000) / answers.length) * (i + 1));
}
this.jsPsych.pluginAPI.clickTarget(display_element.querySelector("#jspsych-survey-text-next"), data.rt);
}
}
SurveyTextPlugin.info = info;
return SurveyTextPlugin;
})(jsPsychModule); CSS to reproduce it: /* ////////////////////////////////////////////////////////// */
/* TRIAL PROCEDURE CSS */
/* ////////////////////////////////////////////////////////// */
.trial_content{
margin-top: 25px;
text-align: center;
}
.container_header{
width:100%;
}
.bullets {
text-align: left;
float: left;
margin-bottom: 25px;
margin-top: 10px;
}
.name{
font-weight: bold;
font-size: 20px;
text-align: right;
float: right;
margin-bottom: 10px;
margin-left: 25px;
border: 1px solid black;
padding: 4px;
}
.head_img{
float: left;
}
.main_body{
float: left;
width:100%;
margin-bottom: 25px;
}
.recommendation{
border: 3px solid;
line-height: 1.4;
padding: 4px 4px;
font-size: 20px;
}
.number_question{
font-size: 20px;
font-weight: bold;
text-align: center;
}
.number_button{
padding: 4px 8px;
margin: 0px;
font-size: 14px;
font-weight: 400;
font-family: 'Open Sans', 'Arial', sans-serif;
cursor: pointer;
line-height: 1.4;
text-align: center;
white-space: nowrap;
vertical-align: middle;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
color: #333;
background-color: #fff;
border-color: #ccc;
}
.number_button:disabled {
background-color: #eee;
color: #aaa;
border-color: #ccc;
cursor: not-allowed;
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
I am trying to present a lot of things above a text input field (the input field is at the bottom of the page). Because the webpage was always displayed at the very bottom of the page, I have added
to the on_load callback. This works fine (i.e., the page is displayed from the top) for Chrome but for some reason I don't understand, it does not in Firefox. Does anyone have an idea what can be done so that upon the trial loading, the page is being scrolled to the top?
I also tried using the window.scrollTo(0,0) command in the on_start callback and in the on_trial_start callback, but it did not work either. Moreover, when manually typing window.scrollTo(0,0) in the Firefox console, it works as it should.
Thanks for any help with this!
Beta Was this translation helpful? Give feedback.
All reactions