Overview
This template enables multiple-choice question functionality within Anki across all major operating systems. Key enhancements include in-review editing capabilities, random option shuffling, and comprehensive score tracking across study sessions.
Recent Updates
20240808 - Selection Preservation Fix: The clear format button previously disrupted text selections when removing formatting from partial selections within nested HTML elements. The solution involves inserting temporary wrapper tags around the selection before HTML modification, then using these markers to restore the original selection via range.selectNode. These temporary elements are automatically stripped during format clearing.
Score Statistics Issue Resolution: Editing notes during review and returning to the review screen previously corrupted score statistics. This requires plugin modifications to distinguish between review and edit contexts.
Plugin Modifications
Simplified Approach (Recommended)
Add a hook handler to detect when the editor context is active:
def setCalc(web_content, context):
"""Prevent score calculation when returning from edit mode"""
if isinstance(context, Editor):
mw.reviewer.web.eval("""
Persistence.setItem(`${deck}.calc`,false);
""")
return
gui_hooks.webview_will_set_content.append(setCalc)
Update the card back template to check the editor status:
var isEditor = $(contenteditable).data('iseditor');
if(isEditor === 'no'){
calcScore();
} else {
pycmd('ankisave!isEditor#');
}
Full Implementation Approach
Step 1: Create reload.py in the plugin directory:
class Reload:
isEditor = 'no'
reload = Reload()
Step 2: Import the reload module in __init__.py.
Step 3: Pass the editor status to the webview via appropriate hook handlers.
Step 4: Handle status modifications in on_js_message(handled, url, context).
Step 5: Expose the reload.isEditor setter to webview for client-side updates.
Card Template Implementation
Required Fields
Configure your note type with these fields:
- Question stem
- Options (A through E or more)
- Correct answer(s)
- Explanation
Front Template
<!--Front Template-->
<script src='_ankiPersistence.js'></script>
<div class='tooltip'>
<span class='tooltiptext'>Enable to use Roman numerals for option numbering.</span>
<input type='checkbox' id='roman' onchange='changeRoman(this)'>
Use Roman Numeral Numbering
</div>
<div class='tooltip'>
<span class='tooltiptext'>Enable to randomize option order each display.</span>
<input type='checkbox' id='shuffle' onchange='changeShuffle(this)' checked>
Randomize Option Order
</div>
<div id='displayArea'>
<div class='question'>{{Question}}</div>
<div class='options' id='optionsContainer'></div>
</div>
<button id='showAnswer' onclick='revealAnswer()'>Show Answer</button>
<button id='showExplanation' onclick='revealExplanation()' style='display:none'>Show Explanation</button>
<div id='resultDisplay'></div>
<div id='statsBar' style='display:none'></div>
Back Template
<!--Back Template-->
<script src='_ankiPersistence.js'></script>
<script src='_jquery.mark.es6.js'></script>
<div class='tooltip'>
<span class='tooltiptext'>Toggle between Roman and Latin numbering.</span>
<input type='checkbox' id='roman' onchange='changeRoman(this)'>
Use Roman Numeral Numbering
</input>
</div>
<div class='tooltip'>
<span class='tooltiptext'>Toggle option randomization.</span>
<input type='checkbox' id='shuffle' onchange='changeShuffle(this)' checked>
Randomize Options
</input>
</div>
<div class='content' contenteditable="true" id='editableContent'>
{{Question}}
<div id='optionsDisplay'></div>
</div>
<div class='toolbar'>
<button onclick='insertBold()'><strong>B</strong></button>
<button onclick='insertItalic()'><em>I</em></button>
<button onclick='insertUnderline()'><u>U</u></button>
<button onclick='insertCode()'></></button>
<button onclick='insertLink()'>🔗</button>
<button onclick='clearFormat()'>Clear Format</button>
</div>
<div class='answer-section' id='answerSection' style='display:none'>
<button onclick='toggleAnswer()'>Toggle Answer Display</button>
<div id='correctAnswer' style='display:none'></div>
</div>
<div class='explanation' id='explanationArea' contenteditable="true">
{{Explanation}}
</div>
<div id='searchBox'>
<input type='text' id='searchInput' placeholder='Search explanation...'>
<button onclick='performSearch()'>Search</button>
<button onclick='clearSearch()'>Clear</button>
</div>
<div id='scoreBoard'></div>
<div id='sessionStats'></div>
Key Features
Option Numbering: Choose between Roman numerals (I, II, III) and Latin letters (A, B, C) for option labels. The template automatically detects single-answer versus multiple-answer questions based on answer length.
Random Shuffling: Toggle option randomization per card or globally. When shuffling occurs, the template maintains internal mapping between display positions and original answer positions.
Persistent Statistics: Track cumulative performance across a study session, displaying results with distinct visual indicators for correct, incorrect, and pending responses.
In-Review Editing: Modify note content directly from the review screen using the contenteditable field. Quick-style buttons provide common formatting operations.
Search with Highlighting: Locate specific text within explanations and highlight matches. Clear the search field to remove highlighting before closing the card.
Per-Deck Statistics: When studying multiple decks in one session, each deck's statistics remain independent.
External Dependencies
-
Anki Persistence Module from SimonLammer's GitHub repository, saved as
_ankiPersistence.jsin your collection.media folder -
jQuery Mark Plugin (jquery.mark.es6.min.js), saved as
_jquery.mark.es6.jsin collection.media -
Edit Field During Review Plugin (ID: 1020366288) - optional but required for in-review editing. Modify the plugin to support HTML insertion and deck name passing to editable fields.
CSS Styles
.tooltip { position: relative; display: inline-block; }
.tooltip .tooltiptext {
visibility: hidden;
width: 200px;
background-color: #333;
color: #fff;
text-align: center;
padding: 8px;
border-radius: 4px;
position: absolute;
z-index: 1;
bottom: 100%;
}
.tooltip:hover .tooltiptext { visibility: visible; }
.content { padding: 10px; border: 1px solid #ccc; }
.toolbar button {
margin: 2px;
padding: 4px 8px;
cursor: pointer;
}
mark { background-color: yellow; padding: 0 2px; }
Important Notes
When editing fields during review, note that any changes to options or correct answers may require manual score recalculation. The template provides toggle buttons to show and modify the current answer configuration when needed.
All score statistics persist across card reviews within a session, and the template automatically handles session boundaries when exiting and re-entering the review screen.