0 votes
ago in SoSci Survey (English) by s306607 (150 points)
edited ago by s306607

I have made the changes as suggested and here is the console view. The results are as expected but I am not sure where they are stored and how to access them. Could you please guide me with that? Thanks :)

ago by SoSci Survey (348k points)
Looks good, so far. The IV01 question is located on the same page like the JavaScript (both on page 1), right? What does the debug information show, when you clicked "next" after the "store data..." information has appeared in the browser console?
ago by s306607 (150 points)
It says the following:

[Information]    Keine Antwort für IV01_01

I am not sure why this is the case.
ago by SoSci Survey (348k points)
Okay, let's add dome more debugging:

function updateHiddenInput() {
        console.log("Store data", videoStats);
        document.getElementById('IV01_01').value = JSON.stringify(videoStats);
        console.log(document.getElementById('IV01_01'));
        console.log(document.getElementById('IV01_01').value);
}

What does the console say?
ago by s306607 (150 points)
While debugging it still says:

[Information]    Keine Antwort für IV01_01

Is it maybe some error in the code or hopefully not but maybe a naming error somewhere?
ago by SoSci Survey (348k points)
Please post the output from the browser console. Thank you.
ago by s306607 (150 points)
I have attached the picture to the edited question. thank you so much for your help, just one more help required about accessing this data :)
ago by SoSci Survey (348k points)
Hmm, can you make sure to place the "internal variables" question above the script, please? I wonder why the second entry in your console is empty. The value, however, seems to be written. When you click the "next" button, then, does the debug information still tell you that there is no data? for IV01_01? Do you have any <input id="IV01_01"> in your code? If that is the case, make sure to remove that.
ago by s306607 (150 points)
there is no <input id="IV01_01">, here is the debug information:
[Information]    Interview Nummer 106 wird fortgesetzt
[Information]    Der Fragebogen base im Projekt media wird verwendet
[Information]    Die Verweildauer auf Seite 1 war 150 Sekunden
[Verarbeitung]    Lese Antworten von Seite 1
[Information]    Keine Antwort für IV01_01
[Verarbeitung]    Erstelle die letzte Seite des Fragebogens

<script>
  var videoList = [
    { id: 'video1', src: 'https://', label: 'Video 1' },
    { id: 'video2', src: 'https://', label: 'Video 2' },
    { id: 'video3', src: 'https://', label: 'Video 3' }
  ];

  
  function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
      let j = Math.floor(Math.random() * (i + 1));
      [array[i], array[j]] = [array[j], array[i]];
    }
    return array;
  }
  videoList = shuffleArray(videoList);

var container = document.getElementById('tiktokContainer');
  videoList.forEach(function(video) {
    var item = document.createElement('div');
    item.className = 'tiktok-item';

    var playerWrapper = document.createElement('div');
    playerWrapper.className = 'player-wrapper';
    playerWrapper.id = video.id;

    var videoElem = document.createElement('video');
    videoElem.setAttribute('playsinline', '');
    videoElem.setAttribute('muted', '');
    videoElem.setAttribute('loop', '');
    videoElem.setAttribute('preload', 'auto');
    videoElem.src = video.src;

    playerWrapper.appendChild(videoElem);

    var overlay = document.createElement('div');
    overlay.className = 'tiktok-overlay';
    overlay.innerHTML = '<p>' + (video.label || '') + '</p>';

    item.appendChild(playerWrapper);
    item.appendChild(overlay);
    container.appendChild(item);
  });

  var videoStats = {
      viewCounts: {},
      viewDurations: {},
      displayOrder: []
  };

  var currentVisibleVideoId = null;
  var currentViewStart = null;

  var observer = new IntersectionObserver(function(entries) {
    entries.forEach(function(entry) {
      if (entry.intersectionRatio >= 0.75) {
        var newVideoId = entry.target.querySelector('.player-wrapper').id;
        if (currentVisibleVideoId !== newVideoId) {
          if (currentVisibleVideoId !== null && currentViewStart) {
            var elapsed = Date.now() - currentViewStart;
            videoStats.viewDurations[currentVisibleVideoId] = (videoStats.viewDurations[currentVisibleVideoId] || 0) + elapsed;
            var prevVideoElem = document.querySelector('#' + currentVisibleVideoId + ' video');
            if (prevVideoElem) {
              prevVideoElem.pause();
              document.getElementById(currentVisibleVideoId).classList.remove('active');
            }
          }
          currentVisibleVideoId = newVideoId;
          currentViewStart = Date.now();
          videoStats.viewCounts[newVideoId] = (videoStats.viewCounts[newVideoId] || 0) + 1;
          videoStats.displayOrder.push(newVideoId);

          var currentVideoElem = document.querySelector('#' + newVideoId + ' video');
          if (currentVideoElem) {
            document.getElementById(newVideoId).classList.add('active');
            currentVideoElem.play();
          }
        }
      }
    });
  }, { threshold: [0.75] });

  document.querySelectorAll('.tiktok-item').forEach(function(item) {
    observer.observe(item);
  });

  function scrollToItem(index) {
    var items = document.querySelectorAll('.tiktok-item');
    if (index < 0) index = 0;
    if (index >= items.length) index = items.length - 1;
    items[index].scrollIntoView({ behavior: 'smooth' });
  }
  document.addEventListener('keydown', function(e) {
    var items = document.querySelectorAll('.tiktok-item');
    var currentIndex = 0;
    items.forEach(function(item, i) {
      if (item.querySelector('.player-wrapper').id === currentVisibleVideoId) {
        currentIndex = i;
      }
    });
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      scrollToItem(currentIndex + 1);
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      scrollToItem(currentIndex - 1);
    }
  });


    function updateHiddenInput() {
        console.log("Store data", videoStats);
        document.getElementById('IV01_01').value = JSON.stringify(videoStats);
        console.log(document.getElementById('IV01_01'));
        console.log(document.getElementById('IV01_01').value);
}


  window.addEventListener('beforeunload', function() {
    if (currentVisibleVideoId && currentViewStart) {
      var elapsed = Date.now() - currentViewStart;
      videoStats.viewDurations[currentVisibleVideoId] = (videoStats.viewDurations[currentVisibleVideoId] || 0) + elapsed;
    }
    updateHiddenInput();
  });
</script>
ago by SoSci Survey (348k points)
Would you mind creating a pretest link with debug option an post it? Please make sure that the pretest link starts at the page with the video embedding.
ago by s306607 (150 points)
DId the link work?
ago by SoSci Survey (348k points)
Here's the manual how to create valid pretest links:
https://www.soscisurvey.de/help/doku.php/en:survey:pretest
ago by s306607 (150 points)
Thank you, here is the preview link with debug options: https://www.soscisurvey.de/sfv_media/?act=MSeuZzkzQABdeBPVFXy6FDFI
 the pretest one doesnt have debug option but still here if needed:
https://www.soscisurvey.de/sfv_media/?act=bQP8dzZD8LymPq1cbxwUJnDo

The stats can only be seen in console and for a split second after pressing weiter n debug shows no info.

1 Answer

0 votes
ago by SoSci Survey (348k points)

The stats can only be seen in console and for a split second after pressing weiter n debug shows no info.

Okay, that's probably part of the problem. If I am correct, your Javascript that copies the information into the internal variable, is triggered from leaving the page. That may be too late to send information.

  window.addEventListener('beforeunload', function() {
    if (currentVisibleVideoId && currentViewStart) {
      var elapsed = Date.now() - currentViewStart;
      videoStats.viewDurations[currentVisibleVideoId] = (videoStats.viewDurations[currentVisibleVideoId] || 0) + elapsed;
    }
    updateHiddenInput();
  });

Instead do it before the information is sent, by using SoSciTools.questionnaire.attachCheck for example.

  SoSciTools.questionnaire.attachCheck(function() {
    if (currentVisibleVideoId && currentViewStart) {
      var elapsed = Date.now() - currentViewStart;
      videoStats.viewDurations[currentVisibleVideoId] = (videoStats.viewDurations[currentVisibleVideoId] || 0) + elapsed;
    }
    updateHiddenInput();
    return true;
  });

Note, that the SoSciTools.questionnaire is only available after the page has loaded. So, you need a bit more code:

window.addEventListener("load", function() {
      SoSciTools.questionnaire.attachCheck(function() {
        if (currentVisibleVideoId && currentViewStart) {
          var elapsed = Date.now() - currentViewStart;
          videoStats.viewDurations[currentVisibleVideoId] = (videoStats.viewDurations[currentVisibleVideoId] || 0) + elapsed;
        }
        updateHiddenInput();
        return true;
      });
});

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

...