shuffleList works on AnkiWeb, but not on AnkiDroid 2.20.1

I’m using AndkiDroid 2.20.1 (anki 24.11).

I want to create a simple card template that shuffles the list items in a certain field, let’s say {{Choices}}.

The list I have in {{Choices}} has id="content", e.g.:

<div>[Choices]</div><br>
<ol id="content">
  <li>Choice1 [Front]</li>
  <li>Choice2 [Front]</li>
  <li>Choice3 [Front]</li>
</ol>

And I expect the template below to get the list and show the items in a shuffled order.

<div>{{Front}}</div>
<div>
    {{Choices}}

    <script>
        (function() {
            function isFrontSide() {
                return !document.getElementById("answer");
            }

            function shuffleList() {
                const list = document.getElementById("content");
                if (!list) return;

                const items = list.getElementsByTagName("li");
                const itemsArray = Array.from(items);

                if (itemsArray.length < 2) return; // No need to shuffle

                for (let i = itemsArray.length - 1; i > 0; i--) {
                    const j = Math.floor(Math.random() * (i + 1));
                    [itemsArray[i], itemsArray[j]] = [itemsArray[j], itemsArray[i]];
                }

                // Remove all existing list items
                while (list.firstChild) {
                    list.removeChild(list.firstChild);
                }

                // Append shuffled items back to the list
                itemsArray.forEach(item => list.appendChild(item));
            }

            function initShuffle() {
                if (isFrontSide()) {
                    shuffleList();
                }
            }

            if (document.readyState === "loading") {
                document.addEventListener("DOMContentLoaded", initShuffle);
            } else {
                initShuffle();
            }
        })();
    </script>
</div>

This works without problems on Anki Desktop and AnkiWeb, however, not on my AnkiDroid. What it does:

  1. Notes only show the shuffled list (including the one without id="content") and no other content; for example, “[Choices]” in the example on top is not displayed
  2. It also shuffles other lists that are in other fields, and without id="content"

What’s more, even on AnkiDroid, when I click on the note and view the sample (the ‘eye’ icon), it displays the note as expected without causing the issues above.

I’ve tested the following, and they work fine on my AnkiDroid. But they do a lot more than I need to and I would rather fix the template above also to avoid having to reorganize all the notes I have.

Any advice would be appreciated.

I do this with some of my cards. I works without add-ins and works on iOS and PC. I haven’t tested on Android, but it should work.

First update your divs by adding style and order. Take a look at my example. The most important piece is the id name…so we can find in using javascript. Also the order style inside the div.

I am not writing a very detailed answer, but if you have questions, let me know and I can do a better job of explaining.

Long story short I display 3 possible answers on the front in a random order. (It is randomized each time the front card is displayed. Then on the back card, I render the answers in the same order as the front and circle the answer using a style.

I have not tried to use user selections because my cards are suppose to be fast to review, but I can see updating the div to include and radio option and then tracking which was selected in a JS variable so that I can get that selection on the back of the card.

For my cards I have a

Add to the Styling at the bottom. This controls the direction of the divs when they are displayed


.multi {
	display:flex;
	flex-direction:column;
}

Front Card

<div class="multi">
	<div id="yourDivName1" style="order:1;">{{YourField1}}</div>
	<div id="yourDivName2" style="order:2;">{{YourField2}}</div>
	<div id="yourDivName3" style="order:3;">{{YourField3}}</div>
</div>

Back Card

<div class="multi">
	<div id="yourDivName1A" style="order:1;" class="rcorners">
		<div>{{YourField1}}</div>
		<div class="normalText focused">{{OtherFieldIfYouWant1}}</div>
	</div>
	<div id="yourDivName2A" style="order:2;border-color:transparent"  class="rcorners">
		<div>{{YourField2}}</div>
		<div>{{OtherFieldIfYouWant2}}</div>
	</div>
	<div id="yourDivName3A" style="order:3;border-color:transparent"  class="rcorners">
		<div>{{YourField3}}</div>
		<div>{{OtherFieldIfYouWant3}}</div>
	</div>
</div>

Then add this script to the bottom of the Front Card

<script>
answer = [];

function orderDivs(amount){
	let sentences = [];
	

	for(counter = 0; counter < amount; counter++) {
		sentences[counter] = "yourDivName" +  (counter + 1);			
	}

	for(counter = 0; counter < amount; counter++) {
		let rnd = Math.floor(Math.random() * sentences.length);

		// set div
		document.getElementById(sentences[rnd]).style.order = (counter + 1);
	
		answer[counter] = sentences[rnd];		

		// remove array element
		sentences.splice(rnd, 1);				
	}

}

orderDivs(3);  // Call the function with the number of options you have.  
</script>

And this script to the back card

<script>
	for(counter = 0; counter < answer.length; counter++)
	{
		//console.log("output %s",answer[counter]);
		let divFound = document.getElementById(answer[counter] + "A");

		divFound.style.order = (counter + 1);
	}

</script>

Thanks for your tip!! That’s very helpful.