Anki Forums

Javascript seed for dynamic content?

tl;dr: Is it possible to get the ordinal number of the current review attempt (the current question-answer combination) into a card template? Like, for an ability to write “this is the 19th attempt of the day” on each card?
(Edit:) Without using an add-on.

When practicing grammar, for example, I feel like it’s a good thing to get away from repeating set phrases, to something more dynamic, to train the actual pattern. E.g. if I want to learn to ask someone’s name, it’d be better not just to practice “How old is Alice?”, but also “How old is Bob?”, “How old is Charlie?”, “How old is he?”, etc. (To/from some other language.)

Having to create multiple notes per pattern is, of course, not desired, so I actually developed a way to get dynamic content on cards, without using add-ons. It’s a silly way, using Javascript in the card’s template. I can post the code if anyone cares, but I’ll describe the process for now:

  1. Two fields are used for comma-separated replacement vocabularies. E.g. the answer vocabulary has “Alice,Bob,Charlie,he,she”, while the question vocabulary has “アリス,ボブ,チャーリー,彼,彼女” (same but in Japanese). Each replacement gets its own line in the vocabulary.
  2. The actual question and answer fields are written with replacement symbols: “(Q1)は何歳ですか。” and “How old is (A1)?”. There can be any number of replacements, i.e. “(A1) gave (A2) to (A3) while (A4) was watching”, corresponding to lines in the vocabulary.
  3. Javascript variables are populated with the contents of the vocabulary fields, like “as = `{{Answer Vocabulary}}`;”. These are split by line breaks and commas into arrays of arrays: as[0][0] is “Alice”, as[0][1] is “Bob” etc.
  4. A random number is generated which is used to make random selections for each replacement.
  5. A replacement is done on the card’s “innerHTML”, one for each replacement symbol; e.g. all “(A1)” are replaced by “Bob” and all “(Q1)” by “ボブ”, all “(A2)” by “a fish” and all “(Q2)” by “魚”, etc.

This leads to dynamic cards. A note with 1 replacement with 10 words means there are 10 possible card questions-and-answers; a note with 2 replacements with 10 words each means there are 100 possible questions-and-answers, surely helpful in practicing the actual pattern instead of set phrases.

There’s a problem, however: showing the answer in Anki recreates the page and re-runs the Javascript with a new randomization, leading (most often) to different replacements. I therefore made a work-around by using the current minute of the system as seed for the randomization, manually re-generating each new minute, and added a countdown-to-regeneration (to not try to answer a question with too little time left).

It would be far preferable to use for example the ordinal number of the current review as seed: knowing that this is the nth review of the day would allow for a seed that is (1) time-independent, and (2) the same for both front and back cards. Something like “{{::counter::}}” -> “19” would be ideal. Is this information available (edit: without add-ons)? Or does someone know of an alternative or have other suggestions (perhaps some way to store the seed between page loadings).

you can assign a JS variable to {{info-Reviews:}} - number of reviews that you had on a card. it is accumulative. I don’t think this add-on support counting for just the same day, although you could implement it in the custom fields section.

Thanks, and apologies! I should have specified that I wanted to do it without add-ons.

(Which is not to disregard add-on authors; it’s just my preference.)

I think current implementation by using just JavasScript you cannot access to the information you need

If you just want the front and back to match, you can randomize the question side and persist that data to reuse on the back. https://github.com/SimonLammer/anki-persistence

1 Like

A solution I used in the past to have the same random choice on front and back:
Use the current date (e.g. the day of the month) to pick from a list of options.

This is not an ideal solution of course, as you might review around midnight. Plus it is far away from true randomness. But it is random enough for me, and really simple and short to do in javascript:

let my_options = ['a', 'b', 'c'];
let choice = my_options[new Date().getDate() % my_options.length];

This also has the advantage, that if you fail the card, and relearn it on the same day, you will see the same random choice, which might be beneficial (or not).

6 Likes

Oh! Excellent solution, self-contained and all! Got it working for my use case. Thanks a bunch – not least for Anki itself!

Nice alternative ! I take note.