Javascript in Ankidroid

I wrote a simple JavaScript for test in a card like: window.alert(), but it only worked on Anki desktop
Also, tried to place a iframe with a youtube video, but only works on desktop too

JavaScript works fine in AnkiDroid.

The main difference to Desktop and AnkiMobile is that on AnkiDroid, the whole page gets reloaded with each card, whereas on the other platforms, only certain parts of the page get updated.

I don’t think window.alert() is the best way to test it. You could try something like

document.getElementById("test").innerHTML = "Hello, world!"

Iframes work too. Would you mind sharing the specific iframe HTML so I can check the cause of the issue?

3 Likes

Just tested again and the iframes worked lol
regarding alert() though, it doesn’t work on ankidroid? How can i display an alert box or a pop-up in the app, if possible?

I found this fantastic multiple choice note that works great on AnkiDesktop and AnkiWeb, it randomizes the alternatives, as long as the correct alternative is in bold.

Although the front of the card works normally, it doesn’t work on the back.

Where and how should I put this code?

If anyone can help me, here’s the script:

FRONT:

<section id="kard">
    <article>
        <div class="tags">#tags: {{Tags}}</div>

        {{#Pergunta}}
        <div id="choicesContainer" class="sample">
            {{Pergunta}}
            <ol class="answerList">
                <li id="answer1" class="answer">{{Resposta-1}}</li>
                <li id="answer2" class="answer">{{Resposta-2}}</li>
                <li id="answer3" class="answer">{{Resposta-3}}</li>
                <li id="answer4" class="answer">{{Resposta-4}}</li>
                <li id="answer5" class="answer">{{Resposta-5}}</li>
                <li id="answer1" class="answer">{{Resposta-6}}</li>
                <li id="answer2" class="answer">{{Resposta-7}}</li>
                <li id="answer3" class="answer">{{Resposta-8}}</li>
                <li id="answer4" class="answer">{{Resposta-9}}</li>
                <li id="answer5" class="answer">{{Resposta-10}}</li>
                <li id="answer1" class="answer">{{Resposta-11}}</li>
                <li id="answer2" class="answer">{{Resposta-12}}</li>
                <li id="answer3" class="answer">{{Resposta-13}}</li>
                <li id="answer4" class="answer">{{Resposta-14}}</li>
                <li id="answer5" class="answer">{{Resposta-15}}</li>
            </ol>
        </div>
        {{/Pergunta}}
    </article>
</section>

<script>
    var arrayElements = [];

    ((function () {
        var hasReview = typeof (review) !== 'undefined' && review.arrayElements;
        var parent = document.getElementsByClassName('answerList')[0];
        var elements = [...document.getElementsByClassName('answer')];

        var elementAnswer = elements.find(c => [...c.childNodes].find(d => d.nodeName == 'B') && (c.innerText = c.innerText));
        if (!elementAnswer) {
            var el = document.getElementById('choicesContainer');
            el.style = "color:#D7DEE9";
            el.innerHTML = 'Necessário a resposta correta estar <b>NEGRITADA</b>.';
        } else {
            elementAnswer.setAttribute('data-correct', true);
        }

        elements.forEach(c => {
            c.id = Math.floor(Math.random() * 1000);
            arrayElements.push(parent.removeChild(c));
        });

        arrayElements = hasReview ? review.arrayElements : arrayElements;

        arrayElements.sort((a, b) => a.id - b.id);
        arrayElements.filter(c => c.innerText.trim().length)
            .forEach(d => parent.append(d));

        if (!hasReview) {
            review = {
                arrayElements
            };
        } else {
            review = undefined
        }
    }))()
</script>

BACK:

<section id="kard">
    <article>
        <div class="tags">#tags: {{Tags}}</div>

        {{#Pergunta}}
        <div id="choicesContainer" class="sample">
            {{Pergunta}}
            <ol class="answerList">
                <li id="answer1" class="answer">{{Resposta-1}}</li>
                <li id="answer2" class="answer">{{Resposta-2}}</li>
                <li id="answer3" class="answer">{{Resposta-3}}</li>
                <li id="answer4" class="answer">{{Resposta-4}}</li>
                <li id="answer5" class="answer">{{Resposta-5}}</li>
                <li id="answer1" class="answer">{{Resposta-6}}</li>
                <li id="answer2" class="answer">{{Resposta-7}}</li>
                <li id="answer3" class="answer">{{Resposta-8}}</li>
                <li id="answer4" class="answer">{{Resposta-9}}</li>
                <li id="answer5" class="answer">{{Resposta-10}}</li>
                <li id="answer1" class="answer">{{Resposta-11}}</li>
                <li id="answer2" class="answer">{{Resposta-12}}</li>
                <li id="answer3" class="answer">{{Resposta-13}}</li>
                <li id="answer4" class="answer">{{Resposta-14}}</li>
                <li id="answer5" class="answer">{{Resposta-15}}</li>
            </ol>
        </div>
        {{/Pergunta}}
    </article>
</section>

<script>
    var arrayElements = [];

    ((function () {
        var hasReview = typeof (review) !== 'undefined' && review.arrayElements;
        var parent = document.getElementsByClassName('answerList')[0];
        var elements = [...document.getElementsByClassName('answer')];

        var elementAnswer = elements.find(c => [...c.childNodes].find(d => d.nodeName == 'B') && (c.innerText = c.innerText));
        if (!elementAnswer) {
            var el = document.getElementById('choicesContainer');
            el.style = "color:#D7DEE9";
            el.innerHTML = 'Necessário a resposta correta estar <b>NEGRITADA</b>.';
        } else {
            elementAnswer.setAttribute('data-correct', true);
        }

        elements.forEach(c => {
            c.id = Math.floor(Math.random() * 1000);
            arrayElements.push(parent.removeChild(c));
        });

        arrayElements = hasReview ? review.arrayElements : arrayElements;

        arrayElements.sort((a, b) => a.id - b.id);
        arrayElements.filter(c => c.innerText.trim().length)
            .forEach(d => parent.append(d));

        if (!hasReview) {
            review = {
                arrayElements
            };
        } else {
            review = undefined
        }
    }))()
</script>
    <article id="extraContainer" class="extraContainer">
        {{#Extra}}
        <span class="extraTitle">Extra</span><br>{{Extra}}
        {{/Extra}}
    </article>
</section>
<script>
    const answer = arrayElements.find(c => c.getAttribute('data-correct') == 'true');
    if (answer) {
        answer.style.color = "#3fc178";
        answer.style.fontWeight = 'bold';

    }
    review = undefined;
</script>

In my posts, I always point out that I don’t know how to code anything at all, so I end up depending on the goodwill of those who know and I’m very grateful for any help they can provide me.

Thank you.

If you send me a link to that template, I’ll check out its syntax and then send you a better one working one that uses Closet under the hood.

1 Like

That would be fantastic.

This note is as I explained above, you have the first field with the questions and then fifteen more fields with alternatives that appeared if they were filled with an answer, the correct answer must be in bold and will be highlighted on the back of the card. The answers are always randomized, with a feature that I think is really cool: the first presents “a)”, the second “b)”, the third “c” and so on as if it were in a test.

Problems with the note:

  1. does not transport information from front to back on AnkiDroid.
  2. sometimes, if two notes of it’s type appear in the same sequence, a kind of bug occurs in which the second note presents the answers of the previous note.

It would be very nice, if not too much work, the possibility of being able to bold more than one correct answer (which is not possible in the current template).

Here is the link to the note file: Multiple-coice note.apkg - Google Drive

Thanks again, you are very kind and helpful.

Here is the promised note type: [Forum] Multiple Choice using Closet - AnkiWeb

image


How to use it

You can either use Closet syntax for multiple choice questions:

[[mc0::right||right::wrong||wrong||wrong]]

or create an unordered (bullet) list and underline the correct list items.

1 Like

You nailed it again, it worked like a charm.

I didn’t quite understand the closet syntax, but the unordered list and underline did the trick, making it very simple.

It will be perfect for all my purposes and it’s working perfectly on AnkiDroid.

Thanks buddy, you needn’t have rushed with this after all the work today with the massive cloze.

You can’t imagine how this will help my studies :smiley:

1 Like