Quiz Card Issue: Value Pass Fix Needed

Hi all!

I’ve been trying to create a new quiz note type using AI for the desktop version of Anki. The note type has 7 fields: question, option1, option2, option3, option4, answer, and SelectedOption.

On the front side, there is a question with 4 options and a submit button that serves two purposes:

  1. Save the selected option.
  2. Flip the card.

When the card flips, the selected option is compared to the answer, and the results are highlighted accordingly:

  • Green if the selected option is correct.
  • Red if the selected option is incorrect, with the correct answer highlighted in green.

I’ve made significant progress, but I’m encountering an issue: the selected option doesn’t seem to be passed from the front side to the back side, so nothing highlights.

Here are the snippets for both sides. I would appreciate any help in resolving this issue.

Front

<div id="question">{{Question}}</div>
<div id="options">
    <input type="radio" id="option1" name="options" value="1">
    <label for="option1">{{Option1}}</label><br>
    <input type="radio" id="option2" name="options" value="2">
    <label for="option2">{{Option2}}</label><br>
    <input type="radio" id="option3" name="options" value="3">
    <label for="option3">{{Option3}}</label><br>
    <input type="radio" id="option4" name="options" value="4">
    <label for="option4">{{Option4}}</label><br>
</div>
<br>
<button onclick="showAnswer()">Show Answer</button>
<script>
    function showAnswer() {
        const options = document.getElementsByName('options');
        let selectedOption = null;
        for (const option of options) {
            if (option.checked) {
                selectedOption = option.value;
                break;
            }
        }

        if (selectedOption !== null) {
            // Store the selected option in a hidden field
            document.getElementById('selectedOption').value = selectedOption;
        }

        if (typeof pycmd === "function") {
            pycmd("ans");
        } else if (typeof anki === "object" && typeof anki.trigger === "function") {
            anki.trigger("ans");
        }
    }
</script>
<input type="hidden" id="selectedOption" name="SelectedOption" value="">

Back

<div id="question">{{Question}}</div>
<div id="options">
    <input type="radio" id="option1" name="options" value="1" disabled>
    <label for="option1">{{Option1}}</label><br>
    <input type="radio" id="option2" name="options" value="2" disabled>
    <label for="option2">{{Option2}}</label><br>
    <input type="radio" id="option3" name="options" value="3" disabled>
    <label for="option3">{{Option3}}</label><br>
    <input type="radio" id="option4" name="options" value="4" disabled>
    <label for="option4">{{Option4}}</label><br>
</div>
<script>
    document.addEventListener("DOMContentLoaded", function() {
        const selectedOption = "{{SelectedOption}}";
        const correctAnswer = "{{Answer}}";

        if (selectedOption) {
            const selectedLabel = document.querySelector('label[for="option' + selectedOption + '"]');
            const correctLabel = document.querySelector('label[for="option' + correctAnswer + '"]');
            
            if (selectedOption === correctAnswer) {
                selectedLabel.style.color = 'green';
            } else {
                selectedLabel.style.color = 'red';
                correctLabel.style.color = 'green';
            }
        }
    });
</script>
<input type="hidden" id="selectedOption" value="{{SelectedOption}}">

If I’m understanding your code correctly, you’re trying to edit the SelectedOption note field during review when the Show Answer button is pressed. I’m pretty sure that’s not possible in the reviewer without using an addon like Edit Field During Review

You can actually just set the selected option value into a variable in the front template and it’ll be transmitted to the card back due to how things work on Anki desktop (everything in the document object, including global variables still exists in the card back even if you don’t use {{FrontSide}} there).

Using pycmd to flip the card will not be necessary as you can store the variable in each option’s onchange handler instead. You can then use Anki’s own Show Answer button normally.

Modified Front:

<script>
    // Reset selected option
    // It will have the value set from the previous card review
    var selectedOption = null;

    // onchange handler for the radio buttons
    function handleSelectOption(event) {
        selectedOption = event.target.value;
    }
</script>
<div id="question">{{Question}}</div>
<div id="options">
    <input type="radio" id="option1" name="options" value="1" onchange="handleSelectOption(event)">
    <label for="option1">{{Option1}}</label><br>
    <input type="radio" id="option2" name="options" value="2" onchange="handleSelectOption(event)">
    <label for="option2">{{Option2}}</label><br>
    <input type="radio" id="option3" name="options" value="3" onchange="handleSelectOption(event)">
    <label for="option3">{{Option3}}</label><br>
    <input type="radio" id="option4" name="options" value="4" onchange="handleSelectOption(event)">
    <label for="option4">{{Option4}}</label><br>
</div>

Modified Back:

<div id="question">{{Question}}</div>
<div id="options">
    <input type="radio" id="option1" name="options" value="1" disabled>
    <label for="option1">{{Option1}}</label><br>
    <input type="radio" id="option2" name="options" value="2" disabled>
    <label for="option2">{{Option2}}</label><br>
    <input type="radio" id="option3" name="options" value="3" disabled>
    <label for="option3">{{Option3}}</label><br>
    <input type="radio" id="option4" name="options" value="4" disabled>
    <label for="option4">{{Option4}}</label><br>
</div>
<script>
    var correctAnswer = "{{Answer}}";

    // The selectedOption global variable set on the Front is available
    // on the Back as well, as Anki desktop preserves the global document object
    // between the Front and the Back and also reviews
    // This does not work on AnkiDroid, as it does not preserve the global object
    // and a different way to transmit the selected option is needed
    if (selectedOption) {
        // Set the selected option too
        document.getElementById('option' + selectedOption).checked = true;
        
        const selectedLabel = document.querySelector('label[for="option' + selectedOption + '"]');
        const correctLabel = document.querySelector('label[for="option' + correctAnswer + '"]');
        
        if (selectedOption === correctAnswer) {
            selectedLabel.style.color = 'green';
        } else {
            selectedLabel.style.color = 'red';
            correctLabel.style.color = 'green';
        }
    }
</script>

In order to transmit a variable (in string format) from front to back in AnkiDroid you need to use this: GitHub - SimonLammer/anki-persistence: Persist data between both sides of an anki flashcard.

1 Like

Hi there!

Thank you for your response.

I was recommended the Anki-persistence library or whatever it’s called. Unfortunately, I couldn’t implement the code for my note type. So, I used an example provided by that guy and modified it a little bit.

I thought that Anki-persistence was required for transmitting information from the front to the back regardless of the Anki client. Personally, I mostly use the desktop version. Does this mean I could’ve made do without Anki-persistence?

That’s right, if you only need this to work on desktop, you don’t need Anki-persistence. I think this code will work on AnkiMobile too, not sure as I’ve never tried it.