AnkiWeb
- Rating
- 8 (π 8 Β· π 0)
- Updated
- 2024-07-18
- Anki versions
- 24.06.3~
- Description language
- en
AnkiWeb addon 1610249201
Creates lists with the shuffle class and randomizes them via a JavaScript script, requiring card-template setup and updated for recent Anki versions.
Open on AnkiWeb GitHub Ask about alternatives
stale
| Min Anki | Max Anki | Updated |
|---|---|---|
| 2.1.15 | 24.06.3+ | 2024-07-18 |
Loadingβ¦
Creates unordered lists whose items shuffle randomly on the front side each review, using a toolbar button or Ctrl+Shift+U and circle bullets.
Customizes Anki editor keymap to insert configured text/HTML or run JavaScript for key-plus-modifier shortcuts, though superseded by other add-ons.
Simplifies managing card template scripts and HTML snippets, enabling reusable JavaScript insertion with conditions, template overwriting, developer hooks, and version updates.
Adds configurable wrapper buttons and shortcuts to Anki for managing cloze navigation, wrapping/unwrapping, centering, citations, mnemonics, shuffling, and custom HTML.
Runs custom JavaScript/Python scripts and inserts symbols/strings in the Anki editor via keyboard shortcuts or popup menus, configured through JSON menus and CodeMirror.
Adds a defease command that uses JavaScript to press the default review button, enabling keyboard-free actions and auto-skipping the back side for correct typed answers.
This repository contains two main components: an Anki add-on and a randomization script:
CTRL+SHIFT+N.Regardless of the card type, you'll need to add the following script, which is responsible for randomizing the lists:
<script data-name="Randomized Lists" data-version="v2.3.0">
// https://github.com/huandney/Anki-Insert-Randomized-Lists
function shuffle(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]];
}
return array;
}
function reorder(elements, indices) {
const children = [...elements.children];
const grouped = [];
for (let i = 0; i < children.length; i++) {
const group = [children[i]];
for (; i + 1 < children.length && children[i + 1].tagName === 'UL'; group.push(children[++i]));
grouped.push(group);
}
const fragment = document.createDocumentFragment();
indices.forEach(index => grouped[index] && grouped[index].forEach(el => fragment.appendChild(el)));
elements.replaceChildren(fragment);
}
function run() {
const uls = document.querySelectorAll('ul.shuffle');
if (!uls || !uls.length) return;
let indices = JSON.parse(sessionStorage.getItem('allIndices')) || {};
if (!document.getElementById('back')) {
uls.forEach((ul, i) => indices[i] = shuffle([...Array(ul.children.length).keys()]));
sessionStorage.setItem('allIndices', JSON.stringify(indices));
}
uls.forEach((ul, i) => reorder(ul, indices[i]));
}
document.addEventListener('DOMContentLoaded', run);
if (document.readyState !== 'loading') run();
</script>
For more details on the script, click here.
These codes are responsible for identifying and maintaining the order of the randomization previously done on the front side. The instructions for inserting the code on the back of the card vary depending on the specific configuration of your card:
<details> <summary><strong>Cards without the FrontSide Field on the Back</strong></summary>
If your card does not have the {{FrontSide}} field, you should add the entire script with the addition of the id="back" to the metadata, as shown below:
<script data-name="Randomized Lists" data-version="v2.3.0" id="back">
// https://github.com/huandney/Anki-Insert-Randomized-Lists
function shuffle(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]];
}
return array;
}
function reorder(elements, indices) {
const children = [...elements.children];
const grouped = [];
for (let i = 0; i < children.length; i++) {
const group = [children[i]];
for (; i + 1 < children.length && children[i + 1].tagName === 'UL'; group.push(children[++i]));
grouped.push(group);
}
const fragment = document.createDocumentFragment();
indices.forEach(index => grouped[index] && grouped[index].forEach(el => fragment.appendChild(el)));
elements.replaceChildren(fragment);
}
function run() {
const uls = document.querySelectorAll('ul.shuffle');
if (!uls || !uls.length) return;
let indices = JSON.parse(sessionStorage.getItem('allIndices')) || {};
if (!document.getElementById('back')) {
uls.forEach((ul, i) => indices[i] = shuffle([...Array(ul.children.length).keys()]));
sessionStorage.setItem('allIndices', JSON.stringify(indices));
}
uls.forEach((ul, i) => reorder(ul, indices[i]));
}
document.addEventListener('DOMContentLoaded', run);
if (document.readyState !== 'loading') run();
</script>
</details>
<details> <summary><strong>Cards with FrontSide Field on the Back</strong></summary>
For cards that use the FrontSide field on the back, you don't need to add the entire script again. Simply insert the following metatag before the {{FrontSide}} field:
<meta id="back">
- This metatag ensures that the script correctly recognizes the back of the card and maintains the randomization order previously set on the front.
- Placing this metatag before the
{{FrontSide}}field is crucial for proper functioning on AnkiDroid. </details>
Modify the add-on settings via Tools β Add-ons (or use CTRL+SHIFT+A) β Insert Randomized Lists, and then click Config. Available options:
hotkey_toggle_list: The hotkey for inserting randomized lists. Default: Alt+Shift+L.enable_custom_style: Enable custom styles for the editor fields. Default: true.custom_style: CSS style to apply to the editor fields.Custom Styles is only for differentiating random lists from regular lists in the editor. This style will not appear when reviewing your cards. If your Anki version is below 2.1.50, the custom style feature is not supported and will be automatically disabled.
sessionStorage.If you are having problems with the add-on, please check the following:
id="back". For cards that use the FrontSide field, the <meta id="back"> tag must be present and should be placed before the {{FrontSide}} field for proper functioning on AnkiDroid. Details here.If you are still encountering issues, or have any suggestions, do not hesitate to open a new issue or PR here. Describe what you are facing in detail, including the Anki version and any error messages you may be receiving.
This project is licensed under the GNU General Public License v3.0.
We would like to thank Glutanimate, the original developer of this add-on. This version has been reformulated and updated for recent Anki versions, but Glutanimate's initial work was instrumental in the development of this project.
Special thanks to kleinerpirat for the Anki CSS Injector add-on, which provided the code for implementing custom styles in the editor fields.