Show a random video from multiple videos

I have cards where a back card has multiple Sound tags with video files. I want only one of them to be randomly selected and appear on the card. Unfortunately, I haven’t been able to do so.

This is what I tried:

Unfortunately it didn’t work, if anyone knows how to do this, please respond.

Finally I came up with this solution:

<script>
  function getButtons() {
    // For Anki desktop
    var buttons = document.querySelectorAll(".soundLink");
    if (buttons.length) return buttons;
    
    // For AnkiDroid
    return document.querySelectorAll(".replaybutton");
  }

  var buttons = getButtons();
  if (buttons.length) {
    var randomIndex = Math.floor(Math.random() * buttons.length);
    for (let i = 0; i < buttons.length; i++) {
      if (i != randomIndex) {
        // Hide other buttons
        buttons[i].style.display = "none";
      }
    }
  }
</script>

Nice that you found a solution on your own!

I got two tips for you, though. Scripts should not be included in the fields themselves, but in the card template. And instead of altering attributes/styles directly, it’s better practice to toggle a class on the random replay button and handle the styles in a separate stylesheet. Reason for both of these suggestions is that it will be easier to understand and edit your design when you get back to the code after some time (and for other devs).

Also, there’s no need to use buttons.length in the condition because the NodeList itself is being checked for truthiness, meaning it evaluates to true if it has elements and false if it’s empty.

Example:

Front / Back Template

<!-- field content -->

<script>
  // "soundLink": Anki desktop | "replaybutton": AnkiDroid
  var buttons = document.querySelectorAll(".soundLink, .replaybutton");

  if (buttons) {
    const randomIndex = Math.floor(Math.random() * buttons.length);
    buttons[randomIndex].classList.add("active");
  }
</script>

CSS

.soundLink,
.replaybutton {
  display: none;
}

.soundLink.active,
.replaybutton.active {
  display: inline-block;
}
3 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.