0 votes
in SoSci Survey (English) by s175567 (225 points)
edited by s175567

Hey lovely people.

I would like to record timestamps from 1) when my participants press play on the audio embedded on the page until 2) they finish filling out the question.

I have tried to search the web and here for a solution, but since I am running out of time and don't know any JS, I would very very much appreciate if someone could help me out.

Best regards

by SoSci Survey (327k points)
You will have to do a jump-start in JavaScript, but it's not that hard:
https://www.soscisurvey.de/help/doku.php/en:create:javascript

Then you will need ttriggers when to record the timestamp. To record pressing the play button, you need the "play" event from the video element. Just make sure to record only the first click.

How do you define "finish filling out the question"?

What you will need are two internal variables to store the timestamps. When you are so far (and you tell me their IDs), I'll explain about the LatencyTimer JavaScript.
by s175567 (225 points)
How can I find the "play"-event from the audio element?

It is a cloze test, so finishing the question would be when all empty fields have been filled.  

I have created two internal variables IV01_01 (timestart) and IV01_02 (timestop).
by SoSci Survey (327k points)
> How can I find the "play"-event from the audio element?

You find the events here, for example:
https://www.w3schools.com/tags/ref_av_dom.asp

What you do is using document.getElementById() to get the video element on the page. Then you use the .addEventListener() on this element to attach a handler for the "play" event.

What HTML ID does you <video> tag have?
by s175567 (225 points)
How do I get the handler for the "play"-event? If I inspect the element on the survey page I find this for the play-button: button#playButton.button.playButton. (I have edited the post and added screenshots of the element). Is this the handler?

The ID for the audio I can find in the internal code is a number: 32. Written as intID="32". Is this correct. The code I have until now is this:

var userTimeStart;  
var vid = document.getElementById("32").addEventListener("playButton");
vid.onplay = function() {
    userTimeStart = new Date();
};

The next timestamp should be when the "next" button is pressed, and I think the method SoSciTools.questionnaire.attachCheck() does this?

So something like this:

SoSciTools.questionnaire.attachCheck(function() {
  let userTimeFinished = new Date(); // Get new time
  let diffInSeconds = (userTimeFinished - userTimeStart)

}

If you know where I'm heading and have a simple code for this, I would be very grateful. It is a bit hard to work with the soscitools when all descriptions are in German.

Thank you so much :)
by SoSci Survey (327k points)
The event handler is the JavaScript function that you implement and run when an event is fired. You won't see the event, but have to look up events in the JavaScript reference.

So you were white close. Change the beginning like this (and maybe use a different HTML ID than "32", I am not sure if numbers are valid)

function myOnPlay() {
  userTimeStart = new Date();
  // eventually write it into the internal variable
  document.getElementById("IV01_01", userTimeStart.getTime());
}

var vid = document.getElementById("32");
vid.addEventListener("play", myOnPlay);
by s175567 (225 points)
Thank you!! I have these questions:

1) Is the HTML ID the intID I can find in the internal code on the Compose questionnaire-page? (I have added another screen shot on the post above). I just want to make sure I don't do anything wrong by changing the indID to "myAudio" or using the wrong ID.

2) Does the .attachCheck ensure the timestamp stops when the "next" button is pressed? And does the below look OK?

3) Do I have to save both times into internal variables, or can I just save the difference (the total response time from start of audio to click on "next") as in the last block of code? And is the use of "input" here correct, in order to save the data? I used it from this page: https://www.soscisurvey.de/help/doku.php/de:create:questions:internal#interne_variablen_und_javascript

4) I have many, many pages to post this code to. Do I have to save the data differently or change anything else (other than the HTML ID for the audio)?

function myOnPlay() {
  var userTimeStart = new Date();
  // write it to the internal variable
  document.getElementById("IV01_01", userTimeStart.getTime());
}

var vid = document.getElementById("myAudio");
vid.addEventListener("play", myOnPlay);

SoSciTools.questionnaire.attachCheck(SaveTime() {
  let userTimeFinished = new Date(); // Get new time
  let diffInSeconds = (userTimeFinished - userTimeStart);
  let input = document.getElementById("IV01_02");
  input.value = diffInSeconds;
}

1 Answer

0 votes
by SoSci Survey (327k points)
selected by s175567
 
Best answer

1) Is the HTML ID the intID I can find in the internal code on the Compose questionnaire-page?

No, the HTML ID is something that you write actively in your HTML code:
Media Files in Questionnaires (watch out for id=)

2) Does the .attachCheck ensure the timestamp stops when the "next" button is pressed? And does the below look OK?

Not yet. You will have to (a) write the new timestamp into an internal variable, and you will have to return true in the function to allow the respondent to continue.

I would also recommend to use a different (!) internal variable for this than for any other events, because one may complete answering the question and will then click "next". Just in case, there is another trigger you are using.

3) Do I have to save both times into internal variables, or can I just save the difference (the total response time from start of audio to click on "next") as in the last block of code?

Both is possible. But storing both will simplyfy things if you have strange behavior. For example if one does not play the video, but only clicks on "next". If you have separate timestamps, you will easier understand the -16999922200 in that case :)

And is the use of "input" here correct, in order to save the data?

input is just a variable here. You could as well write:

document.getElementById("IV01_02").value = diffInSeconds;

I wonder why you ask in English here, but cire German manual pages? You are aware, we're sitting in Munich, right?

4) I have many, many pages to post this code to. Do I have to save the data differently or change anything else (other than the HTML ID for the audio)?

Depends on what is changing on the pages. I would strongly (!) recommend to save it once as a text in the list of questions, and use placeholders to add the HTML IDs, using show(). On the page, it could look like this then:

text('JS01', [
  '%videoID%' => 'stimulus1.mp4',
  '%internalA%' => 'IV01_01',
  '%internalB%' => 'IV01_02'
]);

Just keep on testing, keep an eye on the developer console of your browser, and try to use console.log() to see what you JavaScript does and what it does not yet do.

by s175567 (225 points)
Thank you for all your help. Btw I can't speak German; I think the link was changed in the process somehow.

I have one (hopefully) last issue. Nothing gets saved in the variables IV01_01 (+). The internal variables have been dragged into the question (before the JS-code). What can be the issue?

I can't see anything in developer console or console.log(). (Nothing is shown, no error, no nothing). I am thinking it might be the HTML ID of the audio that it doesn't register. I have found the ID using developer tools -> inspector. I was told on another question I had, to embed the audio using HTML5 in order to use more complex operations, but then I have 144 audio files to embed again... and that is quite a lot. Sooo, do you think the HTML ID might be the issue for the data not being saved in the internal variable? And can I go about this another way that doesn't involve re-embedding 144 audio files?

My final code is as following:

<script type="text/javascript">
<!--
function myOnPlay() {
  var userTimeStart = new Date();
  // write it to the internal variable
  document.getElementById("IV01_01", responseStart.getTime());
}

var vid = document.getElementById("audio26");
vid.addEventListener("play", myOnPlay);

SoSciTools.questionnaire.attachCheck(function() {
  let userTimeFinished = new Date(); // Get new time
  document.getElementById('IV01_02').value = userTimeFinished;
  document.getElementById('IV01_03').value = userTimeFinished - userTimeStart;
  return true;
  }

</script>
by SoSci Survey (327k points)
> I can't see anything in developer console or console.log()

Then the respective functions do not run. Start with a console.log("test") at the very beginning.

> I can't see anything in developer console

At least you shall see an error message, because there is a bracket missing at the very end. You have the function SoSciTools.questionnaire.attachCheck() there, but you to not close the round bracket. It should be:

SoSciTools.questionnaire.attachCheck(function() {
  let userTimeFinished = new Date(); // Get new time
  document.getElementById('IV01_02').value = userTimeFinished;
  document.getElementById('IV01_03').value = userTimeFinished - userTimeStart;
  return true;
});

... because the function() {...} is the parameter in the outer function. A bit weired, yes.

Oh, and atoring to the internval variable must not read like this:

document.getElementById("IV01_01", responseStart.getTime());

bit like this:

document.getElementById("IV01_01"). value = responseStart.getTime();

That still won't work, because there is no variable responseStart, but only userTimeStart.

Finally, makre sure to define the variable in the right scrope. You need a

var userTimeStart;

At the very beginning (before the first function) so that it is available in both functions. And you will also have to add some .getTime() in the second function.
by s175567 (225 points)
I can't thank you guys enough! Now everything is working with the code below, except (!) the third internal variable (IV01_03, placeholdername: "%internalC%") doesn't show up in the data table. How can this be?

Below are the code with placeholders. Below that is the PHP-code on the questionnaire page.

<script type="text/javascript">
<!--
var userTimeStart;

function myOnPlay() {
  var userTimeStart = new Date();
  // write it to the internal variable
  document.getElementById("%internalA%").value = userTimeStart.getTime();
}

var vid = document.getElementById("%audioid%");
vid.addEventListener("play", myOnPlay);

SoSciTools.questionnaire.attachCheck(function() {
  let userTimeFinished = new Date(); // Get new time
  document.getElementById("%internalB%").value = userTimeFinished.getTime();
  document.getElementById("%internalC%").value = userTimeFinished.getTime() - userTimeStart.getTime();
  return true;
 });

</script>

show('RT01', [
    '%filename%' => 'pro://A_S2.2_101.flac',
    '%audioid%' => 'a22101',
    '%internalA%' => 'IV01_01',
    '%internalB%' => 'IV01_02',
    '%internalC%' => 'IV01_03'
]);
by SoSci Survey (327k points)
You're welcome :)

You made sure that you have created a third item in IV01, right? I think the error is having one "var" too much in the myOnPlay() function. If you use "var userTimeStart" there, then you create another variable with that name that is independet from the "outside" variable. Therefore, this variable is undefined when it comes to setting the thrid internval variable. Please try this:

function myOnPlay() {
  userTimeStart = new Date();
  // write it to the internal variable
  document.getElementById("%internalA%").value = userTimeStart.getTime();
}
by s175567 (225 points)
Wow, yes! That is of course it. Now everything works :)

Willkommen im Online-Support von SoSci Survey.

Hier bekommen Sie schnelle und fundierte Antworten von anderen Projektleitern und direkt von SoSci Survey.

→ Eine Frage stellen


Welcome to the SoSci Survey online support.

Simply ask a question to quickly get answers from other professionals, and directly from SoSci Survey.

→ Ask a Question

...