N7 Mech N7 Mech - 3 months ago 13
HTML Question

Why autofocus property works only on first trial?

I need to code a number of trials for a JsPsych experiment displaying a simple math question. The user must answer in a textbox as fast as possible and then press the Enter key to move to the next question. And so on.

On each question, a single textarea is shown for the user to type his/her answer, and such textarea must have focus immediately.

I've modified the survey-text plugin to continue through trials by pressing Enter, as well as adding the autofocus property on creation of each textbox. Problem is that autofocus works only for the first trial, and stops working for the rest.

Code is provided below (in order to work, JsPsych folder must be on the same dir):

<!doctype html>
<html>
<head>
<title>Habilidad Aritmetica</title>
<!-- Inicio llamada a libreria JsPsych + Plugin -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="jspsych-5.0.3/jspsych.js"></script>
<!-- Plugin para recibir texto estilo survey -->
<script src="jspsych-5.0.3/plugins/jspsych-survey-text.js"></script>
<!-- Plugin para desplegar elementos tipo instrucciones -->
<script src="jspsych-5.0.3/plugins/jspsych-instructions.js"></script>
<!-- *** CSS *** -->
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="centered">
<script>

var aritm01={
type: 'survey-text',
timeline:[
{
questions:['<p>preg 1</p>']
}
]
};

var aritm02={
type: 'survey-text',
questions:['<p>preg 2</p>']
};

var aritm03={
type: 'survey-text',
questions:['<p>preg 3</p>']
};

function advance(event){
$("textarea").keydown(function(event){
console.log(event.keyCode);
//event.preventDefault();
if (event.keyCode == 13) {
console.log("User pressed enter. Clicking continue button");
var btn = document.getElementById("jspsych-survey-text-next");
btn.click();
//event.preventDefault();
}
});
}

function recoverfocus(event){
$("textarea").focus();
}

var second_battery = [];

second_battery.push(aritm01);
second_battery.push(aritm02);
second_battery.push(aritm03);


jsPsych.init({
timeline: second_battery,
on_finish: function(){
jsPsych.data.localSave('second_battery_results.csv', 'csv');
},
default_iti: 0
});
</script>
</div>
</body>
</html>


From JsPsych's survey-text plugin side, the important change is:

focused_box = $("#jspsych-survey-text-" + i).append('<textarea autofocus onfocus="advance(event)" onblur="recoverfocus(event)" required name="#jspsych-survey-text-response-' + i + '" cols="' + trial.columns[i] + '" rows="' + trial.rows[i] + '"></textarea>');


(yes, I know that in-line javascript is a bad idea, but so far is the only way I managed to make it work)

Stuff I've tried:


  • A lot of similar questions suggest the use of
    getElementById()

    method, or
    getElementsByTagName()
    in order to handle the DOM
    element, but for some reason none of them works.

  • I've also tried
    using a timer to focus text areas, as suggested here (
    the other solutions suggested on that topic didn't work neither).

  • As you can see from my
    code, I'm trying to "recover" the focus using a function, which
    triggers on Blur. I've also tried such approach onLoad(), with no
    results in both cases.

  • I've tried displaying the questions on a
    nested timeline inside a single trial, instead of using many trials.
    No luck neither.



Am I missing something?

Some extra notes:

As you can guess from this question's tags, JQuery and HTML5 specific functions are totally allowed as solutions, in case that making autofocus work on its own isn't possible. No need to restrict yourselves, have fun.

This behavior has been tested on latest version of Firefox for Ubuntu 16, as well as the latest version of Chrome for Windows (Windows 10 specifically).

UPDATE: You can try this code here

Answer

You can apply the focus after you append the element to the page. In your modified survey-text plugin, try this on line 63:

$("#jspsych-survey-text-" + i +" textarea").focus();

This might make other things that you have in the code obsolete, but I didn't try any other modifications.