# Interactive MCQ Note Type

**URL:** <https://forums.ankiweb.net/t/interactive-mcq-note-type/45858>\
**Category:** Card Design\
**Created:** [June 11, 2024, 11:51am UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858 "2024-06-11T11:51:57Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![figo098](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@figo098](https://forums.ankiweb.net/u/figo098)\
**Post date:** [June 11, 2024, 11:51am UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/1 "2024-06-11T11:51:57Z")

</div>

I have a note type of **interactive MCQ**. The note type is really good and worth it. But when i sometimes click an option or always click the show answer button the **back side appears and this delete or reset my choice forcing to choose again**. What should i do?  
I want when i **click an option the back side appears appears automatically** _saving my choice_ as it is.

---

<div class="post-metadata">

**Author:** ![sorata](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/sorata/32/34115_2.png) [@sorata](https://forums.ankiweb.net/u/sorata)\
**Post date:** [June 11, 2024, 12:25pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/2 "2024-06-11T12:25:14Z")

</div>

I think people will need your card template (Front, Back, CSS) to help you from here.

---

<div class="post-metadata">

**Author:** ![figo098](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@figo098](https://forums.ankiweb.net/u/figo098)\
**Post date:** [June 11, 2024, 1:40pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/3 "2024-06-11T13:40:14Z")

</div>

You’re right. I am gonna share them.

---

<div class="post-metadata">

**Author:** ![figo098](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@figo098](https://forums.ankiweb.net/u/figo098)\
**Post date:** [June 11, 2024, 5:32pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/4 "2024-06-11T17:32:21Z")

</div>

**This is the Front Card:**

```auto
<div id="question">{{Question}}</div>

<div id="options-container" class="options">
  <div class="option" data-correct="{{Option1Correct}}">{{Option1}}</div>
  <div class="option" data-correct="{{Option2Correct}}">{{Option2}}</div>
  <div class="option" data-correct="{{Option3Correct}}">{{Option3}}</div>
  <div class="option" data-correct="{{Option4Correct}}">{{Option4}}</div>
</div>

<button id="toggle-explanation">Show Explanation</button>
<div id="explanation" style="display: none;">
  {{Explanation}}
</div>

<script>
function shuffleOptions() {
  const container = document.getElementById('options-container');
  const options = Array.from(container.children);
  for (let i = options.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    container.appendChild(options[j]);
  }
}

function checkAnswer(optionElement) {
  const isCorrect = optionElement.getAttribute('data-correct') === 'true';
  if (isCorrect) {
    optionElement.style.backgroundColor = 'lightgreen';
    disableAllOptions();
  } else {
    optionElement.style.backgroundColor = 'red';
    revealCorrectAnswer();
    disableAllOptions();
  }
  saveState();
}

function revealCorrectAnswer() {
  const options = document.querySelectorAll('.option');
  options.forEach(option => {
    if (option.getAttribute('data-correct') === 'true') {
      option.style.backgroundColor = 'lightgreen';
    }
  });
}

function disableAllOptions() {
  const options = document.querySelectorAll('.option');
  options.forEach(option => option.onclick = null);
}

function saveState() {
  const options = document.querySelectorAll('.option');
  options.forEach((option, index) => {
    localStorage.setItem(`option-${index}`, option.style.backgroundColor);
  });
}

function loadState() {
  const options = document.querySelectorAll('.option');
  options.forEach((option, index) => {
    const color = localStorage.getItem(`option-${index}`);
    if (color) {
      option.style.backgroundColor = color;
      if (color === 'red' || color === 'green' || color === 'lightgreen') {
        option.style.pointerEvents = 'none';
      }
    }
  });
}

function toggleExplanation() {
  const explanation = document.getElementById('explanation');
  const button = document.getElementById('toggle-explanation');
  if (explanation.style.display === 'none') {
    explanation.style.display = 'block';
    button.textContent = 'Hide Explanation';
  } else {
    explanation.style.display = 'none';
    button.textContent = 'Show Explanation';
  }
}

document.addEventListener('DOMContentLoaded', () => {
  shuffleOptions();
  loadState();
  const options = document.querySelectorAll('.option');
  options.forEach(option => {
    option.onclick = () => checkAnswer(option);
  });
  document.getElementById('toggle-explanation').onclick = toggleExplanation;
});
</script>
<script> function loadState() { const options = document.querySelectorAll('.option'); options.forEach((option, index) => { const color = localStorage.getItem(`option-${index}`); if (color) { option.style.backgroundColor = color; } }); } document.addEventListener('DOMContentLoaded', loadState); 
</script>
**This is the Back Card:**
{{FrontSide}}
**This is the Styling:**.card {
    font-family: arial;
    font-size: 20px;
    text-align: center;
    color: black;
    background-color: white;
}

#question {
  font-size: 24px;
  margin-bottom: 20px;
}

.options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.option {
  padding: 15px;
  border: 2px solid #ccc;
  border-radius: 10px;
  background-color: #f9f9f9;
  cursor: pointer;
  transition: background-color 0.3s;
}

.option:hover {
  background-color: #e0e0e0;
}

#toggle-explanation {
  margin-top: 20px;
  padding: 10px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s;
}

#toggle-explanation:hover {
  background-color: #0056b3;
}

#explanation {
  margin-top: 20px;
  padding: 15px;
  border: 1px solid #ccc;
  border-radius: 10px;
  background-color: #f9f9f9;
}

```

---

<div class="post-metadata">

**Author:** ![figo098](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@figo098](https://forums.ankiweb.net/u/figo098)\
**Post date:** [June 11, 2024, 5:33pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/5 "2024-06-11T17:33:22Z")

</div>

Could anyone edit it

---

<div class="post-metadata">

**Author:** ![NameLessGO](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/namelessgo/32/34298_2.png) [@NameLessGO](https://forums.ankiweb.net/u/NameLessGO)\
**Post date:** [June 11, 2024, 6:00pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/6 "2024-06-11T18:00:58Z")

</div>

# Front

```auto
<div id="question">{{Question}}</div>

<div id="options-container" class="options">
  <div class="option" data-correct="{{Option1Correct}}">{{Option1}}</div>
  <div class="option" data-correct="{{Option2Correct}}">{{Option2}}</div>
  <div class="option" data-correct="{{Option3Correct}}">{{Option3}}</div>
  <div class="option" data-correct="{{Option4Correct}}">{{Option4}}</div>
</div>

<button id="toggle-explanation">Show Explanation</button>
<div id="explanation" style="display: none;">
  {{Explanation}}
</div>

<script>
function shuffleOptions() {
  const container = document.getElementById('options-container');
  const options = Array.from(container.children);
  for (let i = options.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    container.appendChild(options[j]);
  }
}

function checkAnswer(optionElement) {
  const isCorrect = optionElement.getAttribute('data-correct') === 'true';
  if (isCorrect) {
    optionElement.style.backgroundColor = 'lightgreen';
    disableAllOptions();
  } else {
    optionElement.style.backgroundColor = 'red';
    revealCorrectAnswer();
    disableAllOptions();
  }
  saveState();
}

function revealCorrectAnswer() {
  const options = document.querySelectorAll('.option');
  options.forEach(option => {
    if (option.getAttribute('data-correct') === 'true') {
      option.style.backgroundColor = 'lightgreen';
    }
  });
}

function disableAllOptions() {
  const options = document.querySelectorAll('.option');
  options.forEach(option => option.onclick = null);
}

function saveState() {
  const options = document.querySelectorAll('.option');
  options.forEach((option, index) => {
    localStorage.setItem(`option-${index}`, option.style.backgroundColor);
  });
}

function loadState() {
  const options = document.querySelectorAll('.option');
  options.forEach((option, index) => {
    const color = localStorage.getItem(`option-${index}`);
    if (color) {
      option.style.backgroundColor = color;
      if (color === 'red' || color === 'green' || color === 'lightgreen') {
        option.style.pointerEvents = 'none';
      }
    }
  });
}

function toggleExplanation() {
  const explanation = document.getElementById('explanation');
  const button = document.getElementById('toggle-explanation');
  if (explanation.style.display === 'none') {
    explanation.style.display = 'block';
    button.textContent = 'Hide Explanation';
  } else {
    explanation.style.display = 'none';
    button.textContent = 'Show Explanation';
  }
}

document.addEventListener('DOMContentLoaded', () => {
  shuffleOptions();
  loadState();
  const options = document.querySelectorAll('.option');
  options.forEach(option => {
    option.onclick = () => checkAnswer(option);
  });
  document.getElementById('toggle-explanation').onclick = toggleExplanation;
});
</script>
<script> function loadState() { const options = document.querySelectorAll('.option'); options.forEach((option, index) => { const color = localStorage.getItem(`option-${index}`); if (color) { option.style.backgroundColor = color; } }); } document.addEventListener('DOMContentLoaded', loadState); 
</script>

```

# Back:

```auto
{{FrontSide}}

```

# Styling

```auto
.card {
    font-family: arial;
    font-size: 20px;
    text-align: center;
    color: black;
    background-color: white;
}

#question {
  font-size: 24px;
  margin-bottom: 20px;
}

.options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.option {
  padding: 15px;
  border: 2px solid #ccc;
  border-radius: 10px;
  background-color: #f9f9f9;
  cursor: pointer;
  transition: background-color 0.3s;
}

.option:hover {
  background-color: #e0e0e0;
}

#toggle-explanation {
  margin-top: 20px;
  padding: 10px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.3s;
}

#toggle-explanation:hover {
  background-color: #0056b3;
}

#explanation {
  margin-top: 20px;
  padding: 15px;
  border: 1px solid #ccc;
  border-radius: 10px;
  background-color: #f9f9f9;
}

```

---

<div class="post-metadata">

**Author:** ![figo098](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@figo098](https://forums.ankiweb.net/u/figo098)\
**Post date:** [June 11, 2024, 7:10pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/7 "2024-06-11T19:10:51Z")

</div>

Could you please tell what modifications you have done?

---

<div class="post-metadata">

**Author:** ![NameLessGO](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/namelessgo/32/34298_2.png) [@NameLessGO](https://forums.ankiweb.net/u/NameLessGO)\
**Post date:** [June 11, 2024, 7:28pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/8 "2024-06-11T19:28:32Z")

</div>

There wasn’t any modification, this is just front, back and styling separated to help someone more with more knowledge about this topic

---

<div class="post-metadata">

**Author:** ![figo098](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@figo098](https://forums.ankiweb.net/u/figo098)\
**Post date:** [June 11, 2024, 7:37pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/9 "2024-06-11T19:37:04Z")

</div>

Thank you.

---

<div class="post-metadata">

**Author:** ![jhhr](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jhhr/32/21339_2.png) [@jhhr](https://forums.ankiweb.net/u/jhhr)\
**Post date:** [June 14, 2024, 7:04pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/10 "2024-06-14T19:04:05Z")

</div>

You never mentioned which Anki clients you wanted this to work on, desktop, AnkiMobile and/or AnkiDroid.

I’m familiar with the desktop and AnkiDroid javascript quirks but not AnkiMobile specifics, so apologies if this doesn’t work for that. The code below will work on desktop.

# New Front

## Changes

- Removed using an DocumentLoaded eventListener as it wasn’t working for me at least. Not sure if this is a thing in AnkiMobile but in desktop and AnkiDroid I’ve managed without using onloads at all.
- Added a `isBackside` check using a hidden div that only exists on the back side.
- Using `isBackside`, added resetting `localStorage` in the front side. `localStorage` persists after reviews even after closing the deck reviewer on desktop so it needs to be reset on each card.
- Using `isBackside` made it so that the options aren’t shuffled again when switching to back
- Added switching to back side on selecting an option with `pycmd('ans')`. This works on desktop. Not sure about AnkiMobile. AnkiDroid would need to use the AnkiDroid JS API [`showAnswer()`](https://github.com/ankidroid/Anki-Android/wiki/AnkiDroid-Javascript-API#show-answer)

```auto
<div id="question">{{Question}}</div>

<div id="options-container" class="options">
  <div class="option" data-correct="{{Option1Correct}}">{{Option1}}</div>
  <div class="option" data-correct="{{Option2Correct}}">{{Option2}}</div>
  <div class="option" data-correct="{{Option3Correct}}">{{Option3}}</div>
  <div class="option" data-correct="{{Option4Correct}}">{{Option4}}</div>
</div>

<button id="toggle-explanation">Show Explanation</button>
<div id="explanation" style="display: none">{{Explanation}}</div>

<script>
  function shuffleOptions() {
    const container = document.getElementById("options-container");
    const options = Array.from(container.children);
    for (let i = options.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      container.appendChild(options[j]);
    }
  }

  function checkAnswer(optionElement) {
    const isCorrect = optionElement.getAttribute("data-correct") === "true";
    if (isCorrect) {
      optionElement.style.backgroundColor = "lightgreen";
      disableAllOptions();
    } else {
      optionElement.style.backgroundColor = "red";
      revealCorrectAnswer();
      disableAllOptions();
    }
    saveState();
    pycmd("ans");
  }

  function revealCorrectAnswer() {
    const options = document.querySelectorAll(".option");
    options.forEach((option) => {
      if (option.getAttribute("data-correct") === "true") {
        option.style.backgroundColor = "lightgreen";
      }
    });
  }

  function disableAllOptions() {
    const options = document.querySelectorAll(".option");
    options.forEach((option) => (option.onclick = null));
  }

  function saveState() {
    const options = document.querySelectorAll(".option");
    options.forEach((option, index) => {
      localStorage.setItem(`option-${index}`, option.style.backgroundColor);
    });
  }

  function loadState() {
    const options = document.querySelectorAll(".option");
    options.forEach((option, index) => {
      const color = localStorage.getItem(`option-${index}`);
      if (color) {
        option.style.backgroundColor = color;
        if (color === "red" || color === "green" || color === "lightgreen") {
          option.style.pointerEvents = "none";
        }
      }
    });
  }

  function resetState() {
    localStorage.clear();
  }

  function toggleExplanation() {
    const explanation = document.getElementById("explanation");
    const button = document.getElementById("toggle-explanation");
    if (explanation.style.display === "none") {
      explanation.style.display = "block";
      button.textContent = "Hide Explanation";
    } else {
      explanation.style.display = "none";
      button.textContent = "Show Explanation";
    }
  }

  var isBackside = !!document.getElementById("is-backside");
  if (isBackside) {
    shuffleOptions();
  } else {
    resetState();
  }
  loadState();
  var options = document.querySelectorAll(".option");
  options.forEach((option) => {
    option.onclick = () => checkAnswer(option);
  });
  document.getElementById("toggle-explanation").onclick = toggleExplanation;
</script>

```

# New Back

```auto
{{FrontSide}}
<div id='is-backside' style="display: none;"></div>

```

---

<div class="post-metadata">

**Author:** ![sorata](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/sorata/32/34115_2.png) [@sorata](https://forums.ankiweb.net/u/sorata)\
**Post date:** [June 14, 2024, 7:29pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/11 "2024-06-14T19:29:02Z")

</div>

If want to learn about JS for using Anki how should I go about it? You seem like a knowledgeable person so I ask.

My coding experience is basic HTML I learnt in 8th grade in school. Some understanding of CSS gained mostly from observation. Observations that mostly came from Anki’s note templates. I understand the logic behind if { } else { } and basically just that. Is there a good place to start and should I even bother learning it. I don’t want to learn it if it won’t help much with my templates in Anki.

Edit: You’re typing here for an hour? dang. I just expected a quick short answer.

---

<div class="post-metadata">

**Author:** ![jhhr](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jhhr/32/21339_2.png) [@jhhr](https://forums.ankiweb.net/u/jhhr)\
**Post date:** [June 14, 2024, 8:22pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/12 "2024-06-14T20:22:11Z")

</div>

> I don’t want to learn it if it won’t help much with my templates in Anki.

You can do so much with Javascript in templates. Whole addons really.

So then, how best to learn…

Using the method of looking at other people’s code, copy-pasting it and figuring out how it works is a fine way to learn but it does require that you know at least somewhat how to code in general. When you know very little about programming, the difficulty in figuring how some piece of code works is too high. That feels to me very much like the concept of comprehensible input in language learning. If the material is too hard, you learn nothing.

So, I think the main hurdles you have are

1. first learning enough about coding to be able to learn effectively from looking at other people’s code
2. needing to do that on your free time

I’d recommend dong a structured course on javascript programming first. Something on CodeAcademy, udemy, etc. is fine. Then, as soon as you start to feel that you understand what you’d need to learn to do the stuff you’ve been wanting to do, you could stop doing the course and switch to making that stuff you want to make by looking up just what you need to know to do it, copying code from ChatGPT etc.

> You’re typing here for an hour? dang. I just expected a quick short answer.

Haha, I thought so too but then I started thinking about what do I really know about how to learn stuff and went down a rabbit hole. I’m also on team Javascript-addons-are-the-future so I’m happy, if one more person who’s really into Anki also learns Javascript.

---

<div class="post-metadata">

**Author:** ![figo098](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@figo098](https://forums.ankiweb.net/u/figo098)\
**Post date:** [June 15, 2024, 5:51am UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/13 "2024-06-15T05:51:22Z")

</div>

Sorry, i didn’t think of it. I am using **Ankidroid.**

---

<div class="post-metadata">

**Author:** ![jhhr](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jhhr/32/21339_2.png) [@jhhr](https://forums.ankiweb.net/u/jhhr)\
**Post date:** [June 15, 2024, 6:14am UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/14 "2024-06-15T06:14:42Z")

</div>

Okay, well very little needs to be added to make it work on both desktop and AnkiDroid:

# AnkiDroid-compatible Front

- On AnkiDroid, the function to call is `showAnswer()` and on desktop it’s `pycmd("ans")`

```auto
<div id="question">{{Question}}</div>

<div id="options-container" class="options">
  <div class="option" data-correct="{{Option1Correct}}">{{Option1}}</div>
  <div class="option" data-correct="{{Option2Correct}}">{{Option2}}</div>
  <div class="option" data-correct="{{Option3Correct}}">{{Option3}}</div>
  <div class="option" data-correct="{{Option4Correct}}">{{Option4}}</div>
</div>

<button id="toggle-explanation">Show Explanation</button>
<div id="explanation" style="display: none">{{Explanation}}</div>

<script>
  function shuffleOptions() {
    const container = document.getElementById("options-container");
    const options = Array.from(container.children);
    for (let i = options.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      container.appendChild(options[j]);
    }
  }

  function handleShowBackside() {
    try {
      // AnkiDroid
      showAnswer();
    } catch {
      // desktop
      pycmd("ans");
    }
  }

  function checkAnswer(optionElement) {
    const isCorrect = optionElement.getAttribute("data-correct") === "true";
    if (isCorrect) {
      optionElement.style.backgroundColor = "lightgreen";
      disableAllOptions();
    } else {
      optionElement.style.backgroundColor = "red";
      revealCorrectAnswer();
      disableAllOptions();
    }
    saveState();
    handleShowBackside();
  }

  function revealCorrectAnswer() {
    const options = document.querySelectorAll(".option");
    options.forEach((option) => {
      if (option.getAttribute("data-correct") === "true") {
        option.style.backgroundColor = "lightgreen";
      }
    });
  }

  function disableAllOptions() {
    const options = document.querySelectorAll(".option");
    options.forEach((option) => (option.onclick = null));
  }

  function saveState() {
    const options = document.querySelectorAll(".option");
    options.forEach((option, index) => {
      localStorage.setItem(`option-${index}`, option.style.backgroundColor);
    });
  }

  function loadState() {
    const options = document.querySelectorAll(".option");
    options.forEach((option, index) => {
      const color = localStorage.getItem(`option-${index}`);
      if (color) {
        option.style.backgroundColor = color;
        if (color === "red" || color === "green" || color === "lightgreen") {
          option.style.pointerEvents = "none";
        }
      }
    });
  }

  function resetState() {
    localStorage.clear();
  }

  function toggleExplanation() {
    const explanation = document.getElementById("explanation");
    const button = document.getElementById("toggle-explanation");
    if (explanation.style.display === "none") {
      explanation.style.display = "block";
      button.textContent = "Hide Explanation";
    } else {
      explanation.style.display = "none";
      button.textContent = "Show Explanation";
    }
  }

  var isBackside = !!document.getElementById("is-backside");
  if (isBackside) {
    shuffleOptions();
  } else {
    resetState();
  }
  loadState();
  var options = document.querySelectorAll(".option");
  options.forEach((option) => {
    option.onclick = () => checkAnswer(option);
  });
  document.getElementById("toggle-explanation").onclick = toggleExplanation;
</script>

```

---

<div class="post-metadata">

**Author:** ![figo098](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@figo098](https://forums.ankiweb.net/u/figo098)\
**Post date:** [June 15, 2024, 6:38am UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/15 "2024-06-15T06:38:41Z")

</div>

Should i add the back card coding of your **previous message**?

---

<div class="post-metadata">

**Author:** ![jhhr](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jhhr/32/21339_2.png) [@jhhr](https://forums.ankiweb.net/u/jhhr)\
**Post date:** [June 15, 2024, 7:44am UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/16 "2024-06-15T07:44:56Z")

</div>

Yeah, that’s unchanged for the AnkiDroid version

---

<div class="post-metadata">

**Author:** ![figo098](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@figo098](https://forums.ankiweb.net/u/figo098)\
**Post date:** [June 15, 2024, 9:50am UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/17 "2024-06-15T09:50:24Z")

</div>

I am sorry to bother, but the options don’t shuffle anymore. Can you please fix something like that?

---

<div class="post-metadata">

**Author:** ![jhhr](https://sea2.discourse-cdn.com/flex002/user_avatar/forums.ankiweb.net/jhhr/32/21339_2.png) [@jhhr](https://forums.ankiweb.net/u/jhhr)\
**Post date:** [June 15, 2024, 11:04am UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/18 "2024-06-15T11:04:13Z")

</div>

Yeap, passing values from front to back is complicated in AnkiDroid. The selected option and the shuffle state need to be stored in localStorage and then read correctly out, quite a headache.

# Front

- Added another custom attribute `option-index` to each option so you can get the original position from that during shuffling and use it as the key for the shuffled index.
- The code could probably be simplified to make it clearer how the storing and reading works.

```auto
<div id="question">{{Question}}</div>

<div id="options-container" class="options">
  <div class="option" option-index="0" data-correct="{{Option1Correct}}">
    {{Option1}}
  </div>
  <div class="option" option-index="1" data-correct="{{Option2Correct}}">
    {{Option2}}
  </div>
  <div class="option" option-index="2" data-correct="{{Option3Correct}}">
    {{Option3}}
  </div>
  <div class="option" option-index="3" data-correct="{{Option4Correct}}">
    {{Option4}}
  </div>
</div>

<button id="toggle-explanation">Show Explanation</button>
<div id="explanation" style="display: none">{{Explanation}}</div>

<script>
  var isBackside = !!document.getElementById("is-backside");

  function shuffleOptions() {
    const container = document.getElementById("options-container");
    const options = Array.from(container.children);
    // Shuffle the options
    options.sort(() => Math.random() - 0.5);
    options.forEach((option) => {
      container.appendChild(option);
    });
  }

  function handleShowBackside() {
    try {
      // AnkiDroid
      showAnswer();
    } catch {
      // desktop
      pycmd("ans");
    }
  }

  function checkAnswer(optionElement) {
    const isCorrect = optionElement.getAttribute("data-correct") === "true";
    const selectedOriginalIndex = optionElement.getAttribute("option-index");
    if (isCorrect) {
      optionElement.style.backgroundColor = "lightgreen";
    } else {
      optionElement.style.backgroundColor = "red";
      revealCorrectAnswer();
    }
    disableAllOptions();

    localStorage.setItem(
      `option-${selectedOriginalIndex}`,
      optionElement.style.backgroundColor
    );
    saveState();
    handleShowBackside();
  }

  function revealCorrectAnswer() {
    const options = document.querySelectorAll(".option");
    options.forEach((option) => {
      if (option.getAttribute("data-correct") === "true") {
        option.style.backgroundColor = "lightgreen";
      }
    });
  }

  function disableAllOptions() {
    const options = document.querySelectorAll(".option");
    options.forEach((option) => (option.onclick = null));
  }

  function saveState() {
    const options = document.querySelectorAll(".option");
    options.forEach((option, index) => {
      const originalIndex = option.getAttribute("option-index");
      localStorage.setItem(
        `option-${originalIndex}`,
        option.style.backgroundColor
      );
      localStorage.setItem(`shuffle-${originalIndex}`, index);
    });
  }

  function loadState() {
    const options = document.querySelectorAll(".option");
    if (isBackside) {
      const container = document.getElementById("options-container");
      for (let i = 0; i < options.length; i++) {
        const j = localStorage.getItem(`shuffle-${i}`);
        container.appendChild(options[j]);
      }
    }
    options.forEach((option, index) => {
      const color = localStorage.getItem(`option-${index}`);
      if (color) {
        option.style.backgroundColor = color;
        if (color === "red" || color === "green" || color === "lightgreen") {
          option.style.pointerEvents = "none";
        }
      }
    });
  }

  function resetState() {
    localStorage.clear();
  }

  function toggleExplanation() {
    const explanation = document.getElementById("explanation");
    const button = document.getElementById("toggle-explanation");
    if (explanation.style.display === "none") {
      explanation.style.display = "block";
      button.textContent = "Hide Explanation";
    } else {
      explanation.style.display = "none";
      button.textContent = "Show Explanation";
    }
  }
  if (!isBackside) {
    var options = document.querySelectorAll(".option");
    options.forEach((option) => {
      option.onclick = () => checkAnswer(option);
    });
    shuffleOptions();
    resetState();
  } else {
    disableAllOptions();
    loadState();
  }
  document.getElementById("toggle-explanation").onclick = toggleExplanation;
</script>

```

---

<div class="post-metadata">

**Author:** ![figo098](https://avatars.discourse-cdn.com/v4/letter/f/b487fb/32.png) [@figo098](https://forums.ankiweb.net/u/figo098)\
**Post date:** [June 15, 2024, 12:28pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/19 "2024-06-15T12:28:55Z")

</div>

Thank you so much. I appreciate it.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex002/uploads/anki2/original/1X/8f1279ababc5879d54e4838989f606cfe55af8c7.jpeg) [@system](https://forums.ankiweb.net/u/system)\
**Post date:** [July 15, 2024, 12:29pm UTC](https://forums.ankiweb.net/t/interactive-mcq-note-type/45858/20 "2024-07-15T12:29:34Z")

</div>

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