Is it even possible to persist javascript variables on ankidroid?

It is true that Web Storage API, such as sessionStorage, cannot be used to persist variables, but it is possible to store key/value pairs (both strings only) in sessionStorage on the question side, and then retrieve those values on the answer side. Anki-Persistence uses sessionStorage internally for clients like AnkiDroid, where global variables are not persisted.

Suppose you want to keep data between the question and answer on both Anki Desktop and AnkiDroid:

  • If you are using Anki 2.1.49 or earlier, I recommend using Anki-persistence.
  • If you are using Anki 2.1.50 or later, you can simply use sessionStorage, as sessionStorage is also available on Anki desktop.

Here is an example of using sessionStorage to display 3 random fields from 10 fields for both question and answer. ( This script does not work with 2.1.49 or earlier)

Front Template
{{Front}}
<hr>

<div id="fields-output"></div>

<div class="field" hidden>{{Field 01}}</div>
<div class="field" hidden>{{Field 02}}</div>
<div class="field" hidden>{{Field 03}}</div>
<div class="field" hidden>{{Field 04}}</div>
<div class="field" hidden>{{Field 05}}</div>
<div class="field" hidden>{{Field 06}}</div>
<div class="field" hidden>{{Field 07}}</div>
<div class="field" hidden>{{Field 08}}</div>
<div class="field" hidden>{{Field 09}}</div>
<div class="field" hidden>{{Field 10}}</div>

<script>
{
    const fieldCount = 3;
    const fieldsContainer = document.getElementById("fields-output");
    const fields = [...document.querySelectorAll(".field")];
    // Durstenfeld shuffle algorithm
    // https://stackoverflow.com/a/12646864
    function shuffleArray(array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
    }
    const availableFieldIndexes = fields.reduce((prev, current, index) => {
        if (current.textContent.trim()) {
            prev.push(index);
        }
        return prev;
    }, []);
    shuffleArray(availableFieldIndexes);
    const randomIndexes = availableFieldIndexes.slice(0, fieldCount);
    sessionStorage.setItem("randomIndexes", JSON.stringify(randomIndexes));
    for (const index of randomIndexes) {
        fieldsContainer.appendChild(fields[index]);
        fields[index].hidden = false;
    }
}
</script>
Back Template
{{Front}}
<hr>
{{Back}}
<hr>

<div id="fields-output"></div>

<div class="field" hidden>{{Field 01}}</div>
<div class="field" hidden>{{Field 02}}</div>
<div class="field" hidden>{{Field 03}}</div>
<div class="field" hidden>{{Field 04}}</div>
<div class="field" hidden>{{Field 05}}</div>
<div class="field" hidden>{{Field 06}}</div>
<div class="field" hidden>{{Field 07}}</div>
<div class="field" hidden>{{Field 08}}</div>
<div class="field" hidden>{{Field 09}}</div>
<div class="field" hidden>{{Field 10}}</div>

<script>
{
    const fieldCount = 3;
    const fieldsContainer = document.getElementById("fields-output");
    const fields = [...document.querySelectorAll(".field")];
    function shuffleArray(array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
    }
    let randomIndexes;
    if (sessionStorage.getItem("randomIndexes")) {
        randomIndexes = JSON.parse(sessionStorage.getItem("randomIndexes"));
        sessionStorage.clear();
    }
    else {
        // Previewer(if Back Side Only) and Card Layout Editor(Back Template)
        const availableFieldIndexes = fields.reduce((prev, current, index) => {
            if (current.textContent.trim()) {
                prev.push(index);
            }
            return prev;
        }, []);
        shuffleArray(availableFieldIndexes);
        randomIndexes = availableFieldIndexes.slice(0, fieldCount);
    }
    for (const index of randomIndexes) {
        fieldsContainer.appendChild(fields[index]);
        fields[index].hidden = false;
    }
}
</script>

Random Fields (for 2.1.50+ and AnkiDroid).apkg

9 Likes