-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjspsych-button-response.js
152 lines (126 loc) · 4.72 KB
/
jspsych-button-response.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/**
* jspsych-button-response
* Josh de Leeuw
*
* plugin for displaying a stimulus and getting a keyboard response
*
* documentation: docs.jspsych.org
*
**/
jsPsych.plugins["button-response"] = (function() {
var plugin = {};
plugin.trial = function(display_element, trial) {
// default trial parameters
trial.button_html = trial.button_html || '<button class="jspsych-btn">%choice%</button>';
trial.response_ends_trial = (typeof trial.response_ends_trial === 'undefined') ? true : trial.response_ends_trial;
trial.timing_stim = trial.timing_stim || -1; // if -1, then show indefinitely
trial.timing_response = trial.timing_response || -1; // if -1, then wait for response forever
trial.is_html = (typeof trial.is_html === 'undefined') ? false : trial.is_html;
trial.prompt = (typeof trial.prompt === 'undefined') ? "" : trial.prompt;
// if any trial variables are functions
// this evaluates the function and replaces
// it with the output of the function
trial = jsPsych.pluginAPI.evaluateFunctionParameters(trial);
// this array holds handlers from setTimeout calls
// that need to be cleared if the trial ends early
var setTimeoutHandlers = [];
// display stimulus
if (!trial.is_html) {
display_element.append($('<img>', {
src: trial.stimulus,
id: 'jspsych-button-response-stimulus',
class: 'block-center'
}));
} else {
display_element.append($('<div>', {
html: trial.stimulus,
id: 'jspsych-button-response-stimulus',
class: 'block-center'
}));
}
//display buttons
var buttons = [];
if (Array.isArray(trial.button_html)) {
if (trial.button_html.length == trial.choices.length) {
buttons = trial.button_html;
} else {
console.error('Error in button-response plugin. The length of the button_html array does not equal the length of the choices array');
}
} else {
for (var i = 0; i < trial.choices.length; i++) {
buttons.push(trial.button_html);
}
}
display_element.append('<div id="jspsych-button-response-btngroup" class="center-content block-center"></div>')
for (var i = 0; i < trial.choices.length; i++) {
var str = buttons[i].replace(/%choice%/g, trial.choices[i]);
$('#jspsych-button-response-btngroup').append(
$(str).attr('id', 'jspsych-button-response-button-' + i).data('choice', i).addClass('jspsych-button-response-button').on('click', function(e) {
var choice = $('#' + this.id).data('choice');
after_response(choice);
})
);
}
//show prompt if there is one
if (trial.prompt !== "") {
display_element.append(trial.prompt);
}
// store response
var response = {
rt: -1,
button: -1
};
// start time
var start_time = 0;
// function to handle responses by the subject
function after_response(choice) {
// measure rt
var end_time = Date.now();
var rt = end_time - start_time;
response.button = choice;
response.rt = rt;
// after a valid response, the stimulus will have the CSS class 'responded'
// which can be used to provide visual feedback that a response was recorded
$("#jspsych-button-response-stimulus").addClass('responded');
// disable all the buttons after a response
$('.jspsych-button-response-button').off('click').attr('disabled', 'disabled');
if (trial.response_ends_trial) {
end_trial();
}
};
// function to end trial when it is time
function end_trial() {
// kill any remaining setTimeout handlers
for (var i = 0; i < setTimeoutHandlers.length; i++) {
clearTimeout(setTimeoutHandlers[i]);
}
// gather the data to store for the trial
var trial_data = {
"rt": response.rt,
"stimulus": trial.stimulus,
"button_pressed": response.button
};
// clear the display
display_element.html('');
// move on to the next trial
jsPsych.finishTrial(trial_data);
};
// start timing
start_time = Date.now();
// hide image if timing is set
if (trial.timing_stim > 0) {
var t1 = setTimeout(function() {
$('#jspsych-button-response-stimulus').css('visibility', 'hidden');
}, trial.timing_stim);
setTimeoutHandlers.push(t1);
}
// end trial if time limit is set
if (trial.timing_response > 0) {
var t2 = setTimeout(function() {
end_trial();
}, trial.timing_response);
setTimeoutHandlers.push(t2);
}
};
return plugin;
})();